Java: subclass calling parent class methods - java

I have a parent class Shape and a subclass Rectangle, I have a method in parent class Shape called Output.
How can I call the parent class method Output in the children class?
The Parent Class
public class Shape {
public int edge;
public Shape(int Gedge) {
edge=Gedge;
}
public void Output() {
System.out.println("This shape has "+edge+" eges");
}
}
The Subclass:
public class Rectangle extends Shape {
public int edge, length, width;
public Rectangle(int Gedge, int Glength, int Gwidth) {
super (Gedge);
edge=Gedge;
length=Glength;
width=Gwidth;
}
public void Output1() {
//I want to call the parent class Method "Output" here.
System.out.println("The Area is "+length*width);
}
public static void main (String [] args) {
Rectangle A1=new Rectangle(4,3,5);
A1.Output1();
}
}
If I run this code now, the output is The Area is 15, but I want to call the Output method in Shape, so ideally it prints
This shape has 4 edges
The area is 15
Help is Appreciated. Thanks

Just call the method :
public void Output1()
{
Output();
System.out.println("The Area is "+length*width);
}
There's no need for the super keyword, since you are not calling a method of the base class that is overridden by your Output1 method. You are calling a different method.

I think in your example specifically shape must be interface(with method area() and (Rect,Square..) implementing it. Back to your question, because that is in your parent class Output is public you can do from child class this : super.Output();

As others have already answered the question (both call super.Output() or just call Output() are correct), I will attempt to give a little more clarity as to why both are correct (and it's mostly due to your naming conventions).
When you have a parent-child relationship between classes, like so:
class A {
public void doStuff(){
System.out.println("Doing A Stuff!");
}
}
class B extends A {
public void doStuff(){
System.out.println("Doing B Stuff!");
}
}
What you are doing is overriding the doStuff method. The behaviour will be as follows:
A a = new B(); // A is the parent type of a, B is the actual type.
a.doStuff(); // prints "Doing B stuff!"
When you override in Java, the method has to have the exact same name, parameters list (in the same order), and return type. So in your example Output1 is NOT an override of Output. This is why you actually can get away with calling Output() anywhere in your subclass, without the need for the 'super' keyword. If you were to refactor your code so that both methods had the same signature, then yes, the only way to call the behaviour of the parent class is to call super.Output() in the overriding method. In fact, if you then wrote your subclass B in the following way, the call to doStuff would be a recursive call and the method would recurse until you hit a stack overflow (hence, you need to use super.doStuff()):
class B extends A {
public void doStuff(){
doStuff(); // BAD CODE!! Use super.doStuff() here instead!
System.out.println("Doing B Stuff!");
}
}
Another way you could ensure you call the superclass's method is to instantiate the object with an actual type of the supertype, but then you lose all of the functionality of the subclass:
A a = new A(); //both parent type and actual type of a is A
a.doStuff(); // prints "Doing A stuff!" (can't print "Doing B Stuff!")
Also, as commented, you should check out this question which will point you in the direction of official Java style guidelines and conventions. Some quick things to note about your code is the lack of lower camel case for local variables (A1 should be a1) and methods (Output() should be output())

Related

Java inheritance problem. Calling subclass method inside superclass array does not compile

I have a class BaseClass and it has two subclasses C and D. I need to put objects of both C and D type into the array of BaseClass. The assignment works.
But if I call a method print() defined in C and D on the array it will not compile. I am missing something but search on the web or here did not answer my question.
My book says the chain of inheritance will do look for print() in C.
If print() found in C use it. If not found in C go up to parent class.
How to fix?
According to the Java description the inheritance allows a subclass to inherit data and methods from the super class. Furthermore, in the inheritance it says that when a method is invoked on an object the JVM it will first look for the method in the class of the object. If the method is in there it will then use that method. However this following will not compile. The objective is to have an array of the superclass and assign to it objects of the subclasses.
The following is the program.
//This is an example program.
public class Tester
{
static public void main(String[] args)
{
BaseClass[] myarr = new BaseClass[10];
myarr[0] = new C();
myarr[1] = new D();
myarr[0].print(); //error
for (int i =0 ; i < 10; i++)
{
if(myarr[i] != null) myarr[i].print(); //will not compile. Why?
}
}
}
This is the superclass code.
public class BaseClass
{
public BaseClass()
{
}
//it wants print(), why?
}
Next I have two subclasses C and D.
//subclass
public class C extends BaseClass
{
public C()
{
}
public void print()
{
System.out.println(“hello C”);
}
}
And subclass D.
//subclass
public class D extends BaseClass
{
public D()
{
}
public void print()
{
System.out.println(“hello D”);
}
}
It does not work because when creating an Array of Type BaseClass, the compiler does not know anything about a print() method. These just get introduced in your 2 subclasses.
Just imagine you had an other Subclass called E (also extending Baseclass) which did not have a print() function. Now assign an object of E to one of the places in myarr. Until here everything would work fine. Now when you try calling the print() method the compiler would not know what to do. This is why the compiler cannot find print() and does not want to 'interprete' your code.
Now to solve this there are 2 possibilities. If you want a print()-method in every Subclass you could simply create one abstract method:
public abstract class BaseClass {
public BaseClass() {
// Some Constructor Work
}
// This tells the compiler there is a print()-method in every subclass because it must be overridden
public abstract void print();
}
Now in your Subclasses (I just do one for proof of concept :)):
public class SubClass extends BaseClass {
public SubClass() {
// Do Constructor Work if necessary
}
// I would highly suggest you also use this annotation because it helps you
// identifying overridden methods (but it is not obligatory to use)
#Override
public void print() {
System.out.println("Hello from SubClass");
}
}
Now in your main:
public static void main(String[] args) {
// Init Array
BaseClass[] myarr = new BaseClass[4];
myarr[0] = new SubClass();
myarr[1] = new OtherSubClass();
// and so on... I think you get the gist
// Now execute print()
myarr[0].print(); // This works perfectly now.
}
Now possibility 2 which depending on your usecase could be the only working one (though I would highly recommend to use the technique shown before as here you must be 100% certain which ClassType your object is) is a lot unsafer and you must know what you are doing or you get errors (and noone likes errors right? :)): Use Casting.
public static void main(String[] args) { // Note I will be using "your" classes here again
// Array Init...
BaseClass[] myarr = new BaseClass[10];
// Assign blabla
myarr[0] = new C();
myarr[1] = new D();
((C) myarr[0]).print(); // Casting to C-Type which has a print()
}
This will basically tell the compiler (and the JVM): "Hey don't care about what type this object is. Just assume it would be a C-Type!"
I think you start to realize what could be the problem. If the compiler wants to read a C-Type but instead gets a D-Type or an E-Type it does not know what to do --> Error.
Hope I could help you :)
EDIT:
Ah and note that by adding the abstract modifier to a class you cannot create an object of this class any more, just of the corresponding children-classes. This is why I also wanted to give you possibility 2 as this is more versatile.
At compile time, the compiler will check to see that BaseClass has a print() method since the static type of any element in myarr is BaseClass. At runtime, the program will be able to dynamically resolve the type of each object to either C or D. Only then will it look at the C or D classes for their respective print methods. To fix this, you could add a default print method in BaseClass.

Override "private" method in java

There something ambiguous about this idea and I need some clarifications.
My problem is when using this code:
public class B {
private void don() {
System.out.println("hoho private");
}
public static void main(String[] args) {
B t = new A();
t.don();
}
}
class A extends B {
public void don() {
System.out.println("hoho public");
}
}
The output is hoho private.
Is this because the main function is in the same class as the method don, or because of overriding?
I have read this idea in a book, and when I put the main function in another class I get a compiler error.
You cannot override a private method. It isn't visible if you cast A to B. You can override a protected method, but that isn't what you're doing here (and yes, here if you move your main to A then you would get the other method. I would recommend the #Override annotation when you intend to override,
class A extends B {
#Override
public void don() { // <-- will not compile if don is private in B.
System.out.println("hoho public");
}
}
In this case why didn't compiler provide an error for using t.don() which is private?
The Java Tutorials: Predefined Annotation Types says (in part)
While it is not required to use this annotation when overriding a method, it helps to prevent errors. If a method marked with #Override fails to correctly override a method in one of its superclasses, the compiler generates an error.
is this because the main function is in the same class as the method "don"
No, it's because A's don() is unrelated to B's don() method, in spite of having the same name and argument list. private methods are hidden inside their class. They cannot be invoked directly by outside callers, such as main method in your case, because they are encapsulated inside the class. They do not participate in method overrides.
No, a private method cannot be overridden since it is not visible from any other class. You have declared a new method for your subclass that has no relation to the superclass method. One way to look at it is to ask yourself whether it would be legal to write super.func() in the Derived class.
You can't override a private method, but you can introduce one in a derived class without a problem. The derive class can not access the private method on the ancestor.
Since t is a on object of type B, calling don() method will invoque the method defined at B. It doesn't even know that there is a method named also don() at class A
private members aren't visible to any other classes, even children
You can't override a private method, but then again, you can't call it either. You can create an identical method with the same name in the child however.
public class A
{
private int calculate() {return 1;}
public void visibleMethod()
{
System.out.println(calculate());
};
}
public class B extends A
{
private int calculate() {return 2;}
public void visibleMethod()
{
System.out.println(calculate());
};
}
If you call A.visibleMethod() it prints out 1.
If you call B.visibleMethod() it prints 2.
If you don't implement the private calculate() method in B, it won't compile because the public method that calls it can't see the private method in A.

Java inheritance concept

I am a newbie in Java, and would like to understand more about inheritance. Suppose
class Vehicle{
public void move(){
System.out.println(“Vehicles can move”);
}
}
class MotorBike extends Vehicle{
public void move(){
System.out.println(“MotorBike can move and accelerate tool”);
}
}
class Test{
public static void main(String[] args){
Vehicle vh=new MotorBike();
vh.move();
vh=new Vehicle();
vh.move();
}
}
When we do vh.move() in the 1st time it prints MotorBike can move and accelerate tool. Second time it prints Vehicles can move.
It can be called method overriding. Because we have same method name in two class.
But, if two classes have different method, then which method should be called? I want to say like that,
class Vehicle{
public void move(){
System.out.println(“Vehicles can move”);
}
}
class MotorBike extends Vehicle{
public void part(){
System.out.println(“MotorBike can move and accelerate tool”);
}
}
class Test{
public static void main(String[] args){
vehicle a = new vehicle();
Vehicle vh=new MotorBike();
}
}
In the first case vehicle a = new vehicle();it invoke move() and
What will be the second case? If I do `Vehicle vh=new MotorBike();
Which method should be called? move() or part()?
In the second case, even though you have defined an extra method part(), you can only call the move() method (which is inherited from Vehicle) because you have told the compiler that vh is a Vehicle (it doesn't know that it's a Motorbike)
Vehicle vh = new MotorBike(); // from now on, vh is a Vehicle - we don't know it's a MotorBike
vh.move(); // this is fine
vh.part(); // this will not compile
If you want to call the part() method then you have to define the variable as a MotorBike:
MotorBike vh = new MotorBike(); // now we know it's a MotorBike
vh.part(); // this is ok now
it can be called method overridding.becoz we have same method name in
two class.
Well, yes ... but what your code illustrates is that the same method invoked on two objects referenced by the same variable can exhibit different behavior (that is determined by their underlying type). Yes, this requires overloading, but the principle that has been demonstrated is polymorphism.
what will be the 2nd case?if i do Vehicle vh=new MotorBike(); which
method should be called? move() or part()??
In polymorphism, the most specific method in an object hierarchy gets invoked when that method is invoked on an object reference. Consider this example:
public class Parent {
public void emote() {
System.out.println("I'm the parent")'
}
public void parentMethod() { ... }
}
public class Child extends Parent {
#Override
public void emote() {
System.out.println("I'm the child");
}
public void childMethod() { ... }
}
Now consider the following test code:
public void test() {
Parent p1 = new Parent();
p1.emote(); // method invocation prints "I'm the parent"
Parent p2 = new Child();
p2.emote(); // prints "I'm the child"
}
Note that the p2 variable type does not determine the method that gets invoked when the emote() method is called. This is important to understant because a reference variable can point to an object of its own type ... or to any other object that is a subclass of the variable's type.
The method that is invoked is the most specific method that applies to the actual object that is referenced by the variable. In this case, the emote() method on the Child object itself is invoked.
Also, this is valid:
p2.parentMethod();
Even though p2 references a Child object, the Child class inherits the parentMethod() method from it and so the invocation works. These fail, though:
p1.childMethod();
p2.childMethod();
The Parent class does not know anything about the methods that any of its subclasses may define. It may not be intuitive why the second invocation should fail. Although p2 references a Child object, the Parent class does not have a childMethod() declaration. To make this work, we would need to cast p2 to the Child type:
((Child) p2).childMethod();

Superclass method needing to refer to its another (although overridden) method

Having the following superclass:
public class SuperClass {
protected Integer a;
protected Integer b;
public void doSomething() {
this.a = 10;
}
public void doEverything() {
SuperClass.this.doSomething();
this.b = 20;
}
public static void main(String[] args) {
SuperClass instance = new SubClass();
instance.doEverything();
System.out.println(instance.a); //should print 10
System.out.println(instance.b);
}
}
And the following subclass:
public class SubClass extends SuperClass {
#Override
public void doSomething() {
super.doSomething();
super.a *= 10;
}
public void doEverything() {
super.doEverything();
this.b += 5;
}
}
Outputs:
100
25
So, SuperClass.this.doSomething(); is accessing SubClass's doSomething, but I need it to access the SuperClass's doSomething. In that case, I don't have the super keyword, because I'm already on super!
Is there a way to reference¹ the deep SuperClass.this.doSomething, so it would output 10 for the first output value?
¹ I'm interested on referencing: we could, of course, extract the SuperClass's doSomething to an auxiliar private method and access it directly.
If there is no way, does the situation where a superclass method needing to access its another (although overridden) method mean that my OOP design isn't correct? Why?
I assume you come to Java from C++ background. The languages are similar in concepts and in syntax, but they are different in the implementation.
You can achieve what I think is your intention also in Java, but the structure will look differently from C++.
In Java the construct SuperClass.this in your example is exactly the same as this, so SuperClass.this.doSomething(); is exactly what just doSomething() would be. So why does Java at all has the construct SuperClass.this? It has its meaning unrelated to the inheritance. It is useful in the context of nested classes.
Imagine a structure like this:
class A {
class B {
public void doSomething() {
// this here refers to an instance of the class B
System.out.println(this);
// We need to write is this way,
// because this hides the this reference to the instance of A.
// A.this is the instance of A where this is nested
System.out.println(A.this);
}
}
So how can you make sure to be able to have a method in a class that subclasses can override, and still be able to call the specific implementation?
Well, in the strict sense, you cannot. What you can do, is to create a final method, which cannot be overridden, and call it from a non-final method.
class SuperClass {
public void doSomething() {
doSuperClassyThing();
}
public final void doSuperClassyThing() { // cannot be overridden
...
}
}
A similar approach (with a bit different goal) you can see in the Template Method Pattern.
You cannot do what you want. The way polymorphism works is by doing what you are seeing.
That means there is no direct way to call SuperClass.doSomething() from SuperClass.doSomething() without going though SubClass.doSomething() unless you're working with an actual instance of SuperClass.
In some other languages you have power to tell how to handle this for example with keyword virtual in c++, but in java you don't have that option. All the method are being dynamically binded so you cannot do that. You can only not override or prevent it from being overriden at all.
The answer is that you can't refer to it. The only way to do this is the private helper method approach that you are aware of already.
If you want to know the reason why, I guess it's just because it would complicate the language for no reason; you can always get the same result by using a private helper method. The syntax SuperClass.this.doSomething() is already taken for something else. That means calling the method doSomething on the enclosing instance if SuperClass is an enclosing class.
If you ever find yourself on that situation, maybe you should rethink and consider that the class structure is not that correct yet.
Try to implement one of the following approaches:
Composition over Inheritance.
Creating a new Inheritance level (a class in the middle that has a reference to super).
Same as (2.), but using an inner class.
Extract the wanted method to a separate private one and call it where applicable.
Since (1.) wouldn't be as dry as the others, (4.) leaves a feeling of a workaround, and (2.) would require the creation of a new file and would reference outside SuperClass; I think the closest approach would be (3.), which is the only solution that in some way references super inside SuperClass (although it's actually referenced on a SuperClass inner class):
SuperClass.java:
public abstract class SuperClass {
protected Integer a;
protected Integer b;
public void doSomething() {
this.a = 10;
}
public abstract void doEverything();
public static class Impl extends SuperClass {
#Override
public void doEverything() {
super.doSomething();
this.b = 20;
}
}
public static void main(String[] args) {
SuperClass instance = new SubClass();
instance.doEverything();
System.out.println(instance.a); //prints 10
System.out.println(instance.b);
}
}
SubClass.java:
public class SubClass extends SuperClass.Impl {
#Override
public void doSomething() {
super.doSomething();
super.a *= 10;
}
#Override
public void doEverything() {
super.doEverything();
this.b += 5;
}
}

calling parent class method from child class object in java

I have a parent class which has a method, in the child class I override that parent class's method. In a third class I make an object of child and by using that object I want call the method of parent class. Is it possible to call that parent class method ? If yes, then how?
If you override a parent method in its child, child objects will always use the overridden version. But; you can use the keyword super to call the parent method, inside the body of the child method.
public class PolyTest{
public static void main(String args[]){
new Child().foo();
}
}
class Parent{
public void foo(){
System.out.println("I'm the parent.");
}
}
class Child extends Parent{
#Override
public void foo(){
//super.foo();
System.out.println("I'm the child.");
}
}
This would print:
I'm the child.
Uncomment the commented line and it would print:
I'm the parent.
I'm the child.
You should look for the concept of Polymorphism.
Use the keyword super within the overridden method in the child class to use the parent class method. You can only use the keyword within the overridden method though. The example below will help.
public class Parent {
public int add(int m, int n){
return m+n;
}
}
public class Child extends Parent{
public int add(int m,int n,int o){
return super.add(super.add(m, n),0);
}
}
public class SimpleInheritanceTest {
public static void main(String[] a){
Child child = new Child();
child.add(10, 11);
}
}
The add method in the Child class calls super.add to reuse the addition logic.
First of all, it is a bad design, if you need something like that, it is good idea to refactor, e.g. by renaming the method.
Java allows calling of overriden method using the "super" keyword, but only one level up in the hierarchy, I am not sure, maybe Scala and some other JVM languages support it for any level.
Say the hierarchy is C->B->A with A being the base class.
I think there's more to fixing this than renaming a method. That will work but is that a fix?
One way is to refactor all the functionality common to B and C into D, and let B and C inherit from D: (B,C)->D->A Now the method in B that was hiding A's implementation from C is specific to B and stays there. This allows C to invoke the method in A without any hokery.
NOTE calling parent method via super will only work on parent class,
If your parent is interface, and wants to call the default methods then need to add interfaceName before super like IfscName.super.method();
interface Vehicle {
//Non abstract method
public default void printVehicleTypeName() { //default keyword can be used only in interface.
System.out.println("Vehicle");
}
}
class FordFigo extends FordImpl implements Vehicle, Ford {
#Override
public void printVehicleTypeName() {
System.out.println("Figo");
Vehicle.super.printVehicleTypeName();
}
}
Interface name is needed because same default methods can be available in multiple interface name that this class extends. So explicit call to a method is required.

Categories