Say I have the following classes
public abstract class Parent {
public Parent() {
//stuff here
}
}
public class Child extends Parent {
public Child() {
//stuff here
}
public void doSomething() {
}
}
Then I get an object from an array of Parents
public Parent[] parents = new Parent[5];
Parent tempParent = parents[0]
If this object is of the child class, I want to cast the tempParent into the child class in order to use "doSomething" without having to create a new object
if(tempParent.getClass == Child.class) {
tempParent = (Child) tempParent;
tempParent.doSomething();
}
This, however, does not work. I still get an error telling me that doSomething is not a function in the Parent class. Is there a way to do what I'm trying to do?
You need to use the correct TYPE on the LEFT hand side:
Child someChild = (Child) tempParent;
Note: this does not create a new Object.
There is no way of having
Parent whatever = (Child) tempParent;
do what you want to do (invoke a Child class method)!
You see, the compiler only cares about the "defined" type of your reference, it does not take into account that you most likely, at runtime, just "put" something into that reference that in deed is a Child instance!
to do what you want to do.
And note: do not compare objects using ==. You should prefer to call equals() instead. For Class objects == should work (most of the time), but still: get used to check for equality using equals().
I think you're trying to solve the issue from the wrong side.
Technically speaking you should do it like this.
public abstract class Parent {
public Parent() {
//stuff here
}
public abstract void doSomething();
}
public class Child extends Parent {
public Child() {
//stuff here
}
#Override
public void doSomething() {
// Write the code of doSomething specific to child.
}
}
A bit off topic but you might want to consider the following:
I think that the class representation of your code is bad.
I think that you should have 2 concrete classes Parent and Child that are composed or either inherit from a common interface. Even better use composition over inheritance.
https://en.wikipedia.org/wiki/Composition_over_inheritance
if you are able to modify the parent class, I would recommend that you make doSomething an abstract method and have the child class override it. that way, there is no need to cast in order to invoke it.
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
Related
I have the following situation in java; There is a class that implements a method that is meant to be final but I need the returning type of such method to be exactly that of the class that it calling it. Since I want the method to be final I can't modify the return data type in the subclasses since that would be illegal.
Is there a way to archive this without sacrificing finality and having to override such method for all subclasses that implement it?. Even if the method was not final it would still be faster to implement it this way.
The code would be something like this:
class Parent
{
public currentClass finalMethod() {...}
}
class Children extends Parent {}
public static void main(String args[])
{
Children c = new Children();
System.out.print(c.finalMethod().getClass().getName()); // Would print Children
}
Tried to use reflection and generics to no avail. Examples:
class Parent
{
public this.getClass() finalMethod() {...} //Many Errors
public <extends Parent> finalMethod() {...} // Returns Parent even if called by Child
public Class<? extends Parent>[] getVecinos() // Returns Class<? extends Parent> thus can't use polymorphism which is the use case
}
I know I could use casting but still not the best solution.
The default behavior is that you'll get what you're looking for, as long as finalMethod does not generate new instances using other types.
To use your code:
class Parent {
public final Parent finalMethod() {
return this;
}
}
With that, c.finalMethod().getClass().getName() returns Children. That's because this inside finalMethod() is the same object that was created using new Children() and getClass() returns the runtime class of the object.
That uses inheritance and as long as you can work with Parent as the return type, you should be fine. If, however, your objective is to call methods specific to Children on the return value of finalMethod(), you may need to make Parent generic. Something like this:
class Parent<C extends Parent<C>> {
public final Parent<C> finalMethod() {
//whatever
return this;
}
}
class Children extends Parent<Children> {
}
And that would make the following code valid, still producing the same output:
Parent<Children> c = new Children(); //or Children c = new Children();
System.out.print(c.finalMethod().getClass().getName());
This has the advantage of allowing you to make static reference to Child-specific methods without prior casting. But it's not the right solution unless it's okay to make Parent generic. It's also not fail-safe.
I have children classes that use composition with classes that are also children. Instead of having a similar getter in each child class how can I move the getter of the composition class to the parent.
public class child1 extends Parent {
private CoolObjectTypeAAA coolObject;
//coolObject getter
}
public class child2 extends Parent {
private CoolObjectTypeBBB coolObject;
//coolObject getter
}
public class CoolObjectTypeAAA extends CoolObject {
}
public class CoolObjectTypeBBB extends CoolObject {
}
public abstract class Parent {
//would like to have a single CoolObject getter here in parent that returns the appropriate cool object of each child.
}
Is this possible or do I need to just have similar getter in each child class?
How about this:
abstract class Parent<T extends CoolObject> {
protected T mCoolObject;
public Parent(T coolObject) {
mCoolObject = coolObject;
}
public T getCoolObject() {
return mCoolObject;
}
}
class Child1 extends Parent<CoolObjectTypeAAA> {
public Child1(CoolObjectTypeAAA coolObject) {
super(coolObject);
}
public void demoType() {
// This type checks as the return type of getCoolObject() has been refined to CoolObjectTypeAAA
CoolObjectTypeAAA co = this.getCoolObject();
}
}
class Child2 extends Parent<CoolObjectTypeBBB> {
public Child2(CoolObjectTypeBBB coolObject) {
super(coolObject);
}
public void demoType() {
// This type checks as the return type of getCoolObject() has been refined to CoolObjectTypeBBB
CoolObjectTypeBBB co = this.getCoolObject();
}
}
abstract class CoolObject { }
class CoolObjectTypeAAA extends CoolObject { }
class CoolObjectTypeBBB extends CoolObject { }
Essentially you make the subclass specify whatever specific subtype of CoolObject it uses so that it can refine the return type of the getter, yet you get to implement the getter in the super class.
I would suggest taking a look at the abstract factory pattern as this seems to be what you are trying to accomplish. Properly implemented it involves multiple abstract classes and many subclasses but it is not as daunting as it seems.
What you are trying to do basically looks like a compact version of this but it is generally not a great approach as it leads to difficult to follow OO spaghetti code that jumps back and forth between the parent and subclass.
Remember, you've already defined Parent as abstract for a reason.
I suspect your goal is to maximise code reuse, normally when I see this kind of code it is because there is some common "CoolObject" init code that you don't want to duplicate in the child classes.
In that case, it is typically better to write a common "CoolObject" private or protected initializer in the parent but still construct the specific type of CoolObject in the child classes and then initialize it via the parent class method before returning it from the child.
In this case, since it is a getter, there may not be anything other than returning the private object. If that is the case then the best thing is to define a generic getter as abstract in Parent and then redefine in each child. The primary issue with this is that wherever you use this code you will need to continually typecast to the specific type of CoolObject you are expecting.
Because of this, it is likely that down the line, even if you provide either an abstract CoolObject getter or a concrete CoolObject getter in Parent, you will still end up wanting to have concrete implementations of getters for the specific CoolObject types.
The thing to keep in mind when designing something like this is how is it going to be used.
If the goal is to provide an abstraction over the various types of CoolObject then you are basically using a strategy pattern. In this case, being able to cast variables to the sub-type of CoolObject is not needed. In that case a non-specific type getter (abstract or concrete) is feasible.
Having the two specific child classes of Parent, however, it doesn't feel like this is what you are going for. Again I would suggest taking a look at the abstract factory pattern as this seems more like what you trying to do.
Suppose I have the following classes
Class Parent{
public void test(){
System.out.println("Parent");
}
}
Class Child extends Parent{
public void test(){
System.out.println("Child");
}
}
Parent parentE = new Child();
parentE.test();
((Parent)parentE).test();
Output is:
Child
Child
But how can I run parent method in this case using parentE reference?
When you override the parent method, the child object will always call the overriding method (child method) due to Polymorphism.
So in your case either you call the parent method explicitly, inside the child object:
Class Child extends Parent{
public void test(){
super.test();
}
}
Or make a Parent object and call it's method.
Parent parentE = new Parent();
parentE.test();
This is a key feature of polymorphism.
The object you instantiated is an instance of Child. Calling that object's test() is always going to result in the Child's (overridden) test() being called, even if you've assigned that instance to a variable of Parent type.
In short, this is how you can achieve more specific behavior while only having to reference the object using a variable declared a superclass type. Often this is used in conjunction with the base class only providing an abstract method for the subclasses to override.
A trivial example in beginner's books usually involves animals or cars:
public abstract class Animal
{
private final String name;
public Animal(String name)
{
this.name = name;
}
public void printName()
{
System.out.println(name);
}
// more animal general stuff followed by:
public abstract void makeSound();
}
public class Dog extends Animal
{
public Dog()
{
super("Dog");
}
#Override
public void makeSound()
{
System.out.println("Woof!");
}
}
List<Animal> aList = new ArrayList<Animal>();
aList.add(new Dog());
aList.add(new Cat());
// etc
for (Animal a : aList)
{
a.printName();
a.makeSound(); // calls each subclasses' "makeSound()"
}
You can't call the Parent's test() unless you instantiate a Parent or call super.test() from within a method in Child.
(I was actually thinking I could find a good duplicate for this that provided a decent answer, but I couldn't)
Simple
Parent parentE = new Parent();
parentE.test();
In case of method overriding that is resolved at run-time based on actual data type of object not on the basis of referee data type.
You can't call call super class's overridden method directly.
Basically, no, you can't do this, and it would be a bad idea. If Child decides that it needs to override one of its inherited methods, then the outside program shouldn't try to subvert that. It's as though the author of the outside module peeked into the implementation of the methods in Parent and Child and decided "I want the Parent version, not the Child version". But that isn't what OOP is all about. The writer of the outside program should not be concerned with how the method is implemented. See Jon Skeet's answer here, which I think explains this as well as anything I've found.
If you find that you really need to do this, then you have a design issue. The solution is going to depend on your particular project (your original code isn't a real-world example so there's no way to answer it for that). But in some cases, the solution might be that the classes need to provide two different methods that have similar but slightly different purposes. And it may be that in some subclasses of your class, the two methods would have the exact same implementation, but in other subclasses they would be different.
I think you mixed two concepts over here. casting and polymorphism. Read about these concept then things will be more clear for you.
Specifically, why would a variable declared in both a parent and child class be invisible in an instance of the child class passed to a method where the argument is the parent class?
Here is a simplified example of an issue that's puzzling me. There are three classes, a parent and two child subtypes. The classes have a Foo object as a field and this static sort of factory method:
class Parent {
public Foo myFoo;
public static ThinChild createThinChild(Foo someFoo) {
ThinChild thinChild = new ThinChild(someFoo);
return thinChild;
}
public Foo getFoo() {
return myFoo;
}
}
class ThinChild extends Parent {
public Foo myFoo;
public ThinChild(Foo someFoo) {
myFoo = someFoo;
}
}
class ThickChild extends Parent {
public Foo myFoo;
public ThickChild(Foo someFoo) {
myFoo = someFoo;
}
}
Now consider this handler class:
class ChildHandler {
private void doSomethingToThinChild(ThinChild thinChild) {
assert(thinChild.getFoo() != null);
doSomethingToAllChildren(thinChild);
}
private void doSomethingToAllChildren(Parent thinOrThickChild) {
assert(thinOrThickChild.getFoo() != null);
}
}
When I call doSomethingToThinChild, the assert passes. But in the method doSomethingToAllChildren, the assert fails. This is not what I expect.
Moreover, if I add the same exact getFoo method that's in the Parent class to my ThinChild class, the assert now works. Which solves my immediate problem but seems undesirable to me insofar as I'm now maintaining identical code in each of the child classes where I'd prefer just to maintain it in the parent.
My actual case is a bit more complicated, but I hope I've captured all the relevant details. Assuming that I have, is there any explanation for why this would be expected behavior?
It is possible that there's an additional complication in my actual code that I haven't represented here. But I'd first like to confirm that my understanding of class inheritance in Java is sound.
Thanks.
Remove public Foo myFoo. In nested classes, this field extends from parent class. You can't change it because you have 2 variables with same name. So JVM initialized the variable with the smaller scope.
Also the good way is to create constructor in parent:
public Parent(Foo someFoo) {
myFoo = someFoo;
}
and then call it in subclasses:
public ThinChild(Foo someFoo) {
super(someFoo);
}
myFoo is visible from direct child classes, you just have to qualify it with a "super.myFoo". This only works going 1 level up the chain though. so if ThinChild had a subclass ThinnerChild with a myFoo as well, you could not get to instance of "myFoo" which lives in the Parent class. The idea being that you should be able to override your own behavior with your parents, but you should not be able to override your parent (hence why something like super.super is not allowed).
That being said, removing the instances on the child class is most likely what you want, since each ThinChild and ThickChild effectively has two "myFoo" instances in this case, one belonging to it, and one to it's parent.
So I've been trying to find the proper way to get what should be pretty straightforward inheritance to function (the way I want ;)) and I'm failing miserably. Consider this:
class Parent
{
public String name = "Parent";
public Parent() {};
public void doStuff()
{
System.out.println(name);
}
}
class Child extends Parent
{
public String name = "Child";
public Child()
{
doStuff();
}
}
I understand that Java doesn't do what I'd expect in this case as for some reason member variables aren't overridden the same way methods are but my question is what is the proper way to achieve the behavior I'd expect? I'd like my base class to contain some functions that operate on member variables provided/defined by a given subclass. I'd think get/sets could work, but then it destroys my ability to just call super() and have my base class do the construction needed making my subclasses contain a bunch of construction instead of isolating it to the base class.
Any constructive suggestions are welcome.
You can always replace a variable with getter, if you want such kind of 'variable-inheritance'. Not sure if 'variable-inheritance' ((c)) is a good design pattern in general, though.
class Parent {
public void doStuff() {
System.out.println(getName());
}
public String getName() {
return "Parent";
}
}
class Child extends Parent {
public Child() {
doStuff();
}
public String getName() {
return "Child";
}
}
Or you could have protected constructor in Parent class, taking the name to use.
edit
I wouldn't call it a 'hack'. And version with passing parameter into parent constructor can be pretty elegant too.
class Parent {
private final String name;
// don't let use to invoke this constructor, only for child classes
protected Parent(String name) {
this.name = name;
}
// public constructor for users
public Parent() {
this("Parent");
}
public void doStuff() {
System.out.println(name);
}
}
class Child extends Parent {
public Child() {
super("Child");
doStuff();
}
}
do you have any idea why Java seems to have abandoned the concept of inheriting member variables?
Java has abandoned a lot of C++ concepts (starting from infamous multiple inheritance), because they didn't add that much value to the language, but increased its complexity.
Although I don't have anything against variable-inheritance, I'm not suffering without this concept either. And personally, I like the language simple and clean.
Do you really need two different name variables for a single instance? Do you genuinely have the idea of an object having a "name-when-viewed-as-Parent" and a "name-when-viewed-as-Child"? If not, just have a single variable in the Parent class.
How would the Parent class know which variables are going to be provided by the child? If every subclass is going to have the same set of variables, why aren't they in the parent class?
If you could give a more concrete example of the problem you're trying to solve, it would make it easier to give a concrete answer.
The subclass variable name is shadowing the super classes variable of the same name. So when Child declares and assigns name it's another separate variable.
Instead, consider name to be a property of the parent inherited by the child and pass name as an argument to the Parent constructor. Then you would invoke super("Child") from the child constructor.
Also, as a public property, it should be final. Otherwise expose it via getters and setters.
You are correct in that you can't override members of the class. You can achieve this by making name protected and setting it in the constructor.
class Parent {
protected string name;
public Parent() { name = "parent"};
public doStuff() {
System.out.println(name);
}
}
class Child extends Parent {
public Child() {
name = "child";
doStuff();
}
}
What you are trying to do won't work in Java. In Java, attributes declared in a parent class are not overridden in a child class.
If you want polymorphic behavior, then you need to declare the attributes private, and declare corresponding getter methods in the parent class that you can override in the child class.
Alternatively:
class Child extends Parent {
public Child() {
name = "Child";
doStuff();
}
}
though #shoebox639's answer does this in a more elegant way that allows you to declare the attribute as final. (Mutable public attributes are not a good idea ...)
You don't need to redefine your member variable in the subclass. You can write your code as #Stephen C says
class Child extends Parent {
public Child() {
name = "Child";
doStuff();
}
}
In your post
I'd like my base class to contain some functions that operate on member variables provided/defined by a given subclass.
You will write your super class at first and at this stage your super class does not know about your subclass.