Hey i'm trying to call child class method(ChildClass extends SuperClass())
SuperClass s=new ChildClass();
s.childClassMethod();
It doesn't see the ChildClass method the only methods i can call are from SuperClass()
i know it's propably a stupid question but anyway cheers
That's right, you can't see it because s is type SuperClass which doesn't have this method - this would obviously break Polymorphism principle.
So you either have to change the code like ((ChildClass) s).childClassMethod(); or make s as ChildClass type.
Compiler doesn't know what instance this reference would be pointing to at runtime so it will only allow you to access super class's accessible methods at compile time
See
polymorphism
The parent does not know anything about any new methods the child possesses.
public class SuperClass {
// I have no method named "childClassMethod"...
}
public class ChildClass {
public void childClassMethod() {
// Do something.
}
}
SuperClass does not know about childClassMethod(). You would have to provide both classes with an interface or add that method to the parent and override it in the child.
Or, you could simply cast the object to the child class as others have suggested, but this can be unsafe.
((ChildClass) s).childClassMethod()
That is because the super class does not have that method.
If you want the super class to be able to call the method, you need to make it abstract and give it that method.
The subclass is a form of the super class, the super class is not a form of the sub class.
Related
I'm dealing with a class which extends JFrame.
It's not my code and it makes a call to super before it begins constructing the GUI. I'm wondering why this is done since I've always just accessed the methods of the superclass without having to call super();
There is an implicit call to super() with no arguments for all classes that have a parent - which is every user defined class in Java - so calling it explicitly is usually not required. However, you may use the call to super() with arguments if the parent's constructor takes parameters, and you wish to specify them. Moreover, if the parent's constructor takes parameters, and it has no default parameter-less constructor, you will need to call super() with argument(s).
An example, where the explicit call to super() gives you some extra control over the title of the frame:
class MyFrame extends JFrame
{
public MyFrame() {
super("My Window Title");
...
}
}
A call to your parent class's empty constructor super() is done automatically when you don't do it yourself. That's the reason you've never had to do it in your code. It was done for you.
When your superclass doesn't have a no-arg constructor, the compiler will require you to call super with the appropriate arguments. The compiler will make sure that you instantiate the class correctly. So this is not something you have to worry about too much.
Whether you call super() in your constructor or not, it doesn't affect your ability to call the methods of your parent class.
As a side note, some say that it's generally best to make that call manually for reasons of clarity.
None of the above answers answer the 'why'.
Found a good explanation here:
A subclass can have its own private data members, so a subclass can
also have its own constructors.
The constructors of the subclass can initialize only the instance
variables of the subclass. Thus, when a subclass object is
instantiated the subclass object must also automatically execute one
of the constructors of the superclass.
You might also want to read everything about the super keyword here or watch everything about the super keyword here.
We can access super class elements by using super keyword
Consider we have two classes, Parent class and Child class, with different implementations of method foo. Now in child class if we want to call the method foo of parent class, we can do so by super.foo(); we can also access parent elements by super keyword.
class parent {
String str="I am parent";
//method of parent Class
public void foo() {
System.out.println("Hello World " + str);
}
}
class child extends parent {
String str="I am child";
// different foo implementation in child Class
public void foo() {
System.out.println("Hello World "+str);
}
// calling the foo method of parent class
public void parentClassFoo(){
super.foo();
}
// changing the value of str in parent class and calling the foo method of parent class
public void parentClassFooStr(){
super.str="parent string changed";
super.foo();
}
}
public class Main{
public static void main(String args[]) {
child obj = new child();
obj.foo();
obj.parentClassFoo();
obj.parentClassFooStr();
}
}
It simply calls the default constructor of the superclass.
We use super keyword to call the members of the Superclass.
As a subclass inherits all the members (fields, methods, nested classes) from its parent and since Constructors are NOT members (They don't belong to objects. They are responsible for creating objects), they are NOT inherited by subclasses.
So we have to explicitly give the call for parent constructor so that the chain of constructor remains connected if we need to create an object for the superclass. At the time of object creation, only one constructor can be called. Through super, we can call the other constructor from within the current constructor when needed.
If you are thinking why it's there for a class that is not extending any other class, then just remember every class follows object class by default. So it's a good practice to keep super in your constructor.
Note: Even if you don't have super() in your first statement, the compiler will add it for you!
We can Access SuperClass members using super keyword
If your method overrides one of its superclass's methods, you can invoke the overridden method through the use of the keyword super. You can also use super to refer to a hidden field (although hiding fields is discouraged). Consider this class, Superclass:
public class Superclass {
public void printMethod() {
System.out.println("Printed in Superclass.");
}
}
// Here is a subclass, called Subclass, that overrides printMethod():
public class Subclass extends Superclass {
// overrides printMethod in Superclass
public void printMethod() {
super.printMethod();
System.out.println("Printed in Subclass");
}
public static void main(String[] args) {
Subclass s = new Subclass();
s.printMethod();
}
}
Within Subclass, the simple name printMethod() refers to the one declared in Subclass, which overrides the one in Superclass. So, to refer to printMethod() inherited from Superclass, Subclass must use a qualified name, using super as shown. Compiling and executing Subclass prints the following:
Printed in Superclass.
Printed in Subclass
as constructor is not a part of class,
so while calling it cannot be implemented,
by using SUPER() we can call the members and memberfunctions in constructor.
If I create an object of a sub-class with no constructors, then I know that the compiler will implicitly provide a default constructor. What if I create a constructor in the sub-class and try to access the super class constructor using the super keyword, and, now, the super class has no constructor in it. Will the compiler provide a default constructor for the super class as well?
Yes, if there is no specified constructor, there is always default empty constructor
Does the compiler provides a default constructor for the super class also???
The default constructor will be there whether or not there is a subclass that needs it. The default is supplied when the parent is compiled, not later.
...What if I created sub class Constructor and trying to access the super class constructor using the super keyword,and the super class has no constructor in it.
But it does: The default one.
It goes like this.
Lets speak about Object which is the supermost class in java, If you open an editor and just make a class, then it is presumed that It is extending Object. Every class in Java extends from Object. If you do not write your own constructor then Compiler will provide one.
But if you write your own constructor let's say a constructor with one argument, compiler will not provide you with any constructor.
Now lets say taht you extend the above class, then compiler will complain you saying that the superclass does not have a default constructor rather a custom constructor so you need to make one constructor for this child class since first constructor which is called starts from the supermost class that is OBJECT and then proceeds down the line.
Hope this answers comprehensively,
Thanks.
Yes the super always occurs even if you didnt explicit declare
public class FatherTest {
}
public class SonTest extends FatherTest{
public SonTest(String sonName){
super(); // this will always occurs
}
}
If you don't write a constructor for a class, the compiler will implicitly add an empty one for you.
That means this:
public class X {
}
is identical to this:
public class X {
public X() {
// there's also an implicit super(); added here, but that's not directly relevant
}
}
If the super class doesn't have explicit constructor, then an implicit default constructor will be added to it. So your super() will invoke that.
If the super class only have some constructors with parameters. Then super() in the sub-class won't compile. You have to explicitly use one of the defined super-class constructor super(param1, param2, ...), since super() will be called if you don't call it.
Let's consider two classes, SuperClass, and SubClass which extends it:
Class SuperClass{
int superDataMember;
}
Class SubClass extends SuperClass{
int subDataMember;
}
I need to have another CompositeClass class that may use super or sub composition depending on some criteria. My question is: Should I use
An instance of SuperClass inside CompositeClass
Thus, I can use either SuperClass instance or SubClass instance.
But how will methods accessing subDataMember behave if the accessed instance is of SuperClass?
Maybe an instanceOf check may work at the beginning of each method?
Class CompositeClass {
private SuperClass sc;
public getSuperDataMember () {// some code}
public getSubDataMember () {
if (this.sc instanceOf SubClass)
// some code
}
}
An instance of SubClass inside CompositeClass
Thus, I will lose the ability to access SuperClass instances!
Class CompositeClass {
private SubClass sc;
public getSuperDataMember () {// some code}
public getSubDataMember () {// some code
}
}
Implement two versions of CompositeClass, the first is SuperCompositeClass with an instance of SuperClass and the second SubCompositeClass that extends the first with an instance of SubClass!
Mind that a SubClass is also a SuperClass so you won't lose the ability to access the component as a SuperClass like you pointed out.
In addition there is a third option, using parametric polymorphism:
class CompositeClass<T extends SuperClass>
{
private T component;
...
}
So that you can adapt it to the specific situation. This will require you to override additional methods if not provided by the interface of SuperClass though.
It sounds to me from your problem like your two classes might be better as siblings implementing an abstract class's methods than as a parent child relationship. This allows you to easily use polymorphism, using instanceOf if need be. A parent child relationship is most purely used when the child needs to retain all information and functionality of the parent.
I have a superclass Class and a subclass SubClass. Our teacher has asked us to put all the class dependent methods in Class and all the independent ones in SubClass. For example, I need to have the search and sort methods in SubClass.
However, in main, the array list that I work with is defined with the Class constructor and it does not let me call the method from the SubClass to search/sort.
How can I fix that?
Keep in mind that search and sort need to be in the subclass. I cannot put them in the super class just so the program would work.
Thanks!
Don't. That's a terrible idea. Because the sub-class hasn't been instantiated when you're in the super constructor. Instead, you have to finish the construction of your instance(s). Then you can call the method with your variable reference.
For just solving problem at hand. You can call the superclass constructor in subclass and instantiate a subclass object. This will let you instantiate the subclass object on which further you can call your sort etc.
public class SuperClass {
//definition
}
public class SubClass extends SuperClass {
SubClass(//arg) {
super(//arg)
}
}
Hi I have an abstract class which have many subclasses. Id like to make this abstract class' constrcutor private and create factory method. How should this method look like to work in the same way in every sub-class? If I make:
return new AbstractClass();
I get error saying: Class is abstract, cannot be instances... Should I use reflection?
You can access the constructor of the abstract class from the subclasses using the super keyword.
public SubClass() {
super(); // this will call AbstractClass()
// something else that you want to do for this subclass
}
As already pointed out in the comments, you can't use the new keyword with an abstract class. When you use new, you need to know the real type.
You could either implement the factory method in the abstract base class and make it decide which non-abstract subclass to return based on the parameters passed to the create method and/or some internal logic.
Or you could make the factory method itself abstract and implement it in every non-abstract subclass to return an object of that type.