Win a copy of liveProject: Build an ML Recommender System this week in the Artificial Intelligence and Machine Learning forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • paul wheaton
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Liutauras Vilda
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Piet Souris
Bartenders:
  • salvin francis
  • Mikalai Zaikin
  • Himai Minh

Checking the subclass name using class methods?

 
Ranch Hand
Posts: 856
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Example-









my intent here is to know the subclass name, which i will be using in a if condition for computation logic.

I came across two methods
getName and getSimpleName. Based upon the API description, it seems getSimpleName() is appropriate for my use.

Anyway still before using in my code. I want to confirm from you guys, which is the correct way to know the subclass name
from the instance of subclass of type its superclass.
 
Marshal
Posts: 72686
317
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The Class#getName method returns the fully-qualified name and getSimpleName returns the name with the package name taken off.

But how can it be good use of inheritance for a superclass to "know" anything about its subclasses? Subclasses "know" about their superclass, not vice versa.
 
Smart Bear Support
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Per Campbell's reply, you may use either method that you choose, depending on the specificity of the class name you wish to use in your conditional logic. However, I would caution you that this approach is very brittle. If possible, consider other approaches.

  • Are there properties/attributes of the subclasses that determine the appropriate behavior?
  • Is the conditional logic you are implementing more suited to be in each of the subclasses?

  • The problem with dispatching on the instances' class names is unless the class hierarchy is frozen (and the leaf classes are final), your code breaks when the class hierarchy changes. Additional subclasses of the base class could be introduced that you do not handle. If they're not final, additional subclasses of the subclasses could be introduced. Consider the following:
    With this class hierarchy in place, assume the following conditional logic:
    You write your tests and everything appears to be working just fine. Then I come along and introduce the following and your code breaks:
    If instead, your code used getSides() (or any other attribute) to determine the behavior, then your code is much less likely to break. That said, how you ultimately implement your solution is up to you. I just wanted to make you, and others who will read this thread in the future, aware of the issues with using class names in conditional logic.
     
    Amandeep Singh
    Ranch Hand
    Posts: 856
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Brandon DuRette wrote:Per Campbell's reply, you may use either method that you choose, depending on the specificity of the class name you wish to use in your conditional logic. However, I would caution you that this approach is very brittle. If possible, consider other approaches.

  • Are there properties/attributes of the subclasses that determine the appropriate behavior?
  • Is the conditional logic you are implementing more suited to be in each of the subclasses?

  • The problem with dispatching on the instances' class names is unless the class hierarchy is frozen (and the leaf classes are final), your code breaks when the class hierarchy changes. Additional subclasses of the base class could be introduced that you do not handle. If they're not final, additional subclasses of the subclasses could be introduced. Consider the following:
    With this class hierarchy in place, assume the following conditional logic:
    You write your tests and everything appears to be working just fine. Then I come along and introduce the following and your code breaks:
    If instead, your code used getSides() (or any other attribute) to determine the behavior, then your code is much less likely to break. That said, how you ultimately implement your solution is up to you. I just wanted to make you, and others who will read this thread in the future, aware of the issues with using class names in conditional logic.



    Replying to your 1st question-
    No they will not. Because i am calling getSimpleName() on the instance of class variable.

    2nd question-
    Yes it is more suited to the subclaasses only.

    I understand your approach that the code is going to be brittle. But i do not see any other good way to achieve it. Except this below approach.

    Suppose if i do make the superclass like this-



    And only one of the subclass in which i am interested like this-



    Here please not that i am overriding this only in my intentional subclasses. Not all subclasses.


    Do you like this approach ?

    NOTE- This change would require me to change my existing legacy code. I wished, would have made the class superclass as abstract. But that option is not available to me.
     
    Amandeep Singh
    Ranch Hand
    Posts: 856
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Again this code is going to be brittle. Because if someone override the method in any subclass. Things can go wrong.
    In this case, when need to check the instance of particular subclass when number of subclasses are available.
    Hard coding the subclass name only will be the solution.

    Please advise.
     
    author and iconoclast
    Posts: 24203
    44
    Mac OS X Eclipse IDE Chrome
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    You're missing the point. Explain to us why you want to branch based on the class name rather then using a polymorphic abstract method in the parent class. That's the whole point of class inheritance, really; if you're making decisions based on class names, you might as well be writing FORTRAN.
     
    Amandeep Singh
    Ranch Hand
    Posts: 856
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I wish i could have used the polymorphic abstract method. But here I am dealing with legacy code, where the superclass is a plain simple class. Nothing abstract here.
     
    Brandon DuRette
    Smart Bear Support
    Posts: 8
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    In your example, you've demonstrated that you're capable and willing to change the base class, as you added the getSubclassName() method to a. So, the question is, given that you can change all the classes in this class hierarchy, why not add the functionality you need to a and all of its subclasses, rather than trying to dispatch on a name. This is the polymorphic approach.

    Alternatively, think carefully about what it is about each of the subclasses (and the base class) that forces you to have conditional logic in your code. I am certain it's not the name of the subclass as class names are effectively arbitrary tokens, generated by the programmer. If there is no distinguishing characteristic that separates the subclasses, then why have the conditional logic at all? Finally, I will just say that I would prefer using instanceof or getClass().equals(Class.class) to the getClass().getName().equals() approach (but not to the polymorphic approach) simply because the compiler will catch the error when someone renames the subclass.
     
    Amandeep Singh
    Ranch Hand
    Posts: 856
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Example-
    its like this- Superclass a
    subclasses b, c, d

    Inheritance is being used.
    Now when i do have a instance of class b. I want to know it. Because if it is b, i want to ignore some code to run.
    The only way i can know it is class b, by its name.

    Here still c as class name has been hardcoded. I mean to say, there are no perfect solutions.
     
    Ernest Friedman-Hill
    author and iconoclast
    Posts: 24203
    44
    Mac OS X Eclipse IDE Chrome
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Amandeep Singh wrote:. I mean to say, there are no perfect solutions.



    Yes, there is. USE POLYMORPHISM!!!
     
    Amandeep Singh
    Ranch Hand
    Posts: 856
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    So, the question is, given that you can change all the classes in this class hierarchy, why not add the functionality you need to a and all of its subclasses, rather than trying to dispatch on a name. This is the polymorphic approach.



    Can you give me the hint, you are prescribing to add the functionality ?
     
    Author
    Posts: 12617
    IntelliJ IDE Ruby
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Put the subclass functionality in the subclass. Put shared functionality in the base class.
    reply
      Bookmark Topic Watch Topic
    • New Topic