The accepted answer to this question provides a good explanation of the semantic difference between rdfs:subClassOf and owl:equivalentClass.
In the example provided by the OP, the class :Teenager is declared to be a subclass of a data property restriction on the :hasAge property with a value in the range [12:19]. The answer states that the rdfs:subClassOf assertion
means that any instance of Teenager in the OWL ontology must necessarily also have the property hasAge with a value in the range [12:19].
Although this statement may capture the semantics of subclass restrictions in OWL, what is the ultimate value of using them? It seems that not much can be inferred, programmatically, from a subclass restriction. So, is its main utility to document semantic modeling intent? When defining restrictions, why would an ontologist prefer rdfs:subClassOf over owl:equivalentClass?
For example, I encoded the following ontology (in Protégé 5.6.1), based on the OP's example:
@prefix : <urn:test/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@base <urn:test/> .
[ rdf:type owl:Ontology
 ] .
#################################################################
#    Data properties
#################################################################
###  urn:test/hasAge
:hasAge rdf:type owl:DatatypeProperty ;
        rdfs:label "has age" .
#################################################################
#    Classes
#################################################################
###  urn:test/Person
:Person rdf:type owl:Class ;
        rdfs:label "Person" .
###  urn:test/Teenager
:Teenager rdf:type owl:Class ;
          rdfs:subClassOf [ owl:intersectionOf ( :Person
                                                 [ rdf:type owl:Restriction ;
                                                   owl:onProperty :hasAge ;
                                                   owl:someValuesFrom [ rdf:type rdfs:Datatype ;
                                                                        owl:onDatatype xsd:integer ;
                                                                        owl:withRestrictions ( [ xsd:minInclusive 12
                                                                                               ]
                                                                                               [ xsd:maxInclusive 19
                                                                                               ]
                                                                                             )
                                                                      ]
                                                 ]
                                               ) ;
                            rdf:type owl:Class
                          ] ;
          rdfs:label "Teenager" .
#################################################################
#    Individuals
#################################################################
###  urn:test/_car
:_car rdf:type owl:NamedIndividual ;
      :hasAge 13 .
###  urn:test/_chris
:_chris rdf:type owl:NamedIndividual ,
                 :Teenager ;
        :hasAge 20 ;
        rdfs:label "Chris" .
When I run a reasoner (e.g., HermiT), the individual :_chris is still inferred to be a member of the :Teenager class, as asserted, even though the value of :hasAge is outside the defined range--and the ontology is not inferred to be inconsistent (I assume this is due to the Open World Assumption). :_chris is also inferred to be a member of the :Person class--and that's it.
If I run a DL Query in Protégé with the expression 'has age' some xsd:integer[>= 12 , <= 19], it does return :Teenager as a subclass and :_chris and :_car as instances.
Changing the DL query to 'has age' some xsd:integer[>= 12 , <= 42] returns the same results, whereas changing it to 'has age' some xsd:integer[>= 13 , <= 42] removes :Teenager as a subclass. So, that's interesting. Beyond DL queries, are there other standard ways (with current tooling) to leverage a restriction defined with rdfs:subClassOf in OWL?
Ultimately, if my main interest is in deriving new statements based on inferencing and OWL axioms, does a subclass restriction really give me anything of value?