Using super in the sub class to print super class field - java

I ran the following piece of code :
class Feline {
public String type = "f ";
public Feline() {
System.out.print("feline ");
}
}
public class Cougar extends Feline {
public Cougar() {
System.out.print("cougar ");
}
public static void main(String[] args) {
new Cougar().go();
}
void go() {
type = "c ";
System.out.print(this.type + super.type);
}
}
And thought the output would be feline cougar c f but to my surprise output came out to be feline cougar c c.
Can someone please explain.

Superclass is not something a subclass instance has, it is something a subclass instance is. Your Cougar "is a" Feline. All members of Feline are members of Cougar - the same ones, not copies. There is no separate type inside the superclass - it is the same type member as in the subclass. You can refer to it as Cougar's member or as Feline's member, it's all the same.

Sure - you've only got one type variable per instance of Cougar. It's declared in Feline and inherited by Cougar. Wherever you change the value of that variable, it'll be visible everywhere (for that object).
So if you had another method in Feline which printed the current value of type, that would print c as well (after you'd called go()).

You have not coded the field in the subclass:
public class Cougar extends Feline {
public String type = "c ";
// ...
}

Related

Is it possible to call a subclass specific method if only the superclass object has been initialized?

Lets deduct from a very simple example:
Class a:
public class a{
public a{}
Subclass b inherits a:
public class b inherits a{
public b{super}
public void customMethodB(){}
Subclass c inherits a:
public class c inherits a{
public c{super}
public void customMethodC(){}
Main:
public class Main{
public static void main(String[] args){
a newObject = null;
//User can now choose through input if he wants to create b or c. Lets say he creates b:
newObject = new b();
//His choice is stored in a string.
String userChoice = b;
//I now call the general object from another method for the user to interact with.
//(I have a feeling it is here my problem is).
}
userInteraction(a newObject, String userChoice){
if (userChoice.equals("b"){
newObject.customMethodB();
}
else if (userChoice.equals("c"){
newObject.customMethodC();
}
}
Here lies my problem: I can not call customMethodB nor customMethodC even though the object is created as b in main. Is this due to the parameter type being a in the userInteraction method? Would it be possible to do something like this without creating a method to pass the specific subclass type?
Your method customMethodB does not exist in your type a.
In order to call this method, you have to cast your object ( down cast is possible here )
if (userChoice.equals("b") && newObject instanceof b){
((b)newObject).customMethodB();
}

Java - attribute inheritance example

I am puzzled by this inheritance example found in a quizz from a Coursera Java course:
class B is a subclass of class A
class B getPrefix() method overrides class' A method
class B number attribute overrides class' A attribute
class ClassA {
protected int number;
public ClassA() {
number = 20;
}
public void print() {
System.out.println(getPrefix() + ": " + number);
}
protected String getPrefix() {
return "A";
}
}
class ClassB extends ClassA {
protected int number = 10;
protected String getPrefix() {
return "B";
}
}
public class Quizz {
public static void main(String[] args) {
ClassB b = new ClassB();
b.print();
ClassA ab = new ClassB();
ab.print();
}
}
When we run this program, the printed result is:
B: 20
B: 20
However, I was expecting this result instead:
B: 10
B: 10
Can you explain how come class A number attribute is printed, and not class B?
Can you explain how come class A number attribute is printed, and not class B?
ClassB does not inherit ClassA.number field, but rather hides it.
See:
The Java™ Tutorials - Hiding Fields
Within a class, a field that has the same name as a field in the superclass hides the superclass's field.
Yeah so you can override a method from a super class but you cannot declare another class member with the same name. You're creating a new class member with the name number. It would only refer to 10, the value from the super class #number if you used super.number instead of this.number.

what's the use of java virtual method invokation?

Say I have the following code
public class A {
public void callme() {
System.out.println("Calling of class A function ");
}
}
public class B extends A {
public void callme() {
System.out.println(" Calling of class B fuction ");
}
public void Hello() {
System.out.println("hello guys");
}
}
and a main() that does the following
public class Main {
public static void main(String [] args){
A a = new B();
B b = new B();
b = (B)a;
a.callme();
b.callme();
a.Hello(); // show error : Hello is undefined for method A
}
}
The book says "you get the behavior associated with the object to which the variable refers at runtime". Ok, I get behavior of B class when a method callme is called, but when I access the method Hello, it shows an error that Hello is undefined for method A. why is that?
Polymorphism doesn't work this way. Since A is parent of B, B can inherit methods of A (like son can inherit properties of father), but its not vice versa because A doesn't know which classes are inheriting it (A does not know who are its children.)
For Example, suppose there is one more class C:
public class C extends A {
public void callme(){
System.out.println(" Calling of class C fuction ");
}
public void Hello(){
System.out.println("hello guys, I am C");
}
}
Now, if you use
a.Hello();
how will a know which child class it should call since it does not methods of its child. only its own abstract method, which it knows child will implement for sure.
a is of type A, even if it is referring to an instance of B.
A doesn't have the Hello method (even an abstract declaration). So your compiler emits the error. Adjusting your code slightly to
public abstract class A {
public abstract void Hello();
/*the rest as before*/
would be a fix. A is then assuming the characteristics of an interface.
public class B extends A {
public void callme(){
System.out.println(" Calling of class B fuction ");
}
public void Hello(){ // hello method is only the part of class B not A.
System.out.println("hello guys");
}
}
In above class hello() method is a part of B only. it not override by the method of A.
now in your main method call
public static void main(String [] args){
A a= new B(); // object of b referred by (a) Reference Variable of A
B b= new B(); // object of b referred by (b) Reference Variable of B
b= (B)a;
a.callme(); //override takes place and method of B's Callme() called
b.callme(); //again override takes place here and method of B's Callme() called
a.Hello();// buttttttt
b.Hello(); // this will compile and executes fine.
}
}
Here you used the reference variable of class A which don't have any method name Hello(). So, Method Resolution will not take place(won't be able to find any method like Hello()).
but if you try to call b.Hello() using the reference variable of B then it will work fine to you.
Now suppose there is another class C which is a sub class of A and contains a Method Name Hello().
public class C extends A {
public void Hello(){ // hello method is only the part of class B not A.
System.out.println("hello guys");
}
}
In main a Statement like this
A a = new C();
and if you try to call a.Hello() then which Hello() method will call. Compiler will get confused.
So, This concept work only when you try to override the method of super class in sub Class.
Is the parent class aware of classes derived from it ?
Casting does not change the actual object type. Only the reference type gets changed.
I highly recommend you my upcasting and downcasting writing from the link

Inheritance constructor calling result

There are two classes. One inherited from the other one. Test results surprise me
since I called the child class constructor and its method. However I do not call the super class constructor like this new Cougar().go();. But output shows the the super class constructor is called. Could you explain me why this happens?
public class Feline {
public String type = "f";
public Feline() {
System.out.println("feline");
}
}
public class Cougar extends Feline {
public Cougar() {
System.out.println("cougar");
}
public static void main(String[] args) {
new Cougar().go();
}
private void go() {
type = "c";
System.out.println(this.type + " " + super.type);
}
}
Output: feline
cougar
c c
If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass.
The constructor of the superclass is always invoked. You can call the desired constructor of your superclass using "super()" in the first line of your child class constructor.
For example:
public class Feline {
public Feline() {
System.out.println("Feline");
}
public Feline(String type) {
System.out.println(type);
}
...
}
public class Cougar extends Feline{
public Cougar() {
super("Cougar");
}
...
}
It is Because of line
new Cougar().go();
Inside the "go" method you have redefined the variable "type".
I hope it is making sense.
When we invoke child class constructor,the java compiler automatically calls super class
constructor.If it is not present in super class,we will get compile time error.
If Object is the super class of our class then no issue since Object contains no-arg constructor.
Reason- The reason to have super constructor called is that if super class could have private fields which need to be initialized by its constructor.
Refer this link for more info.
When you call parameter-less constructor of the derived class the run-time automatically calls the parameter-less base class constructor before executing the derived class constructor. Because of this behavior you see feline cougar as first two string in your output.
Now for the 'c c' part of the output, you are not defining new String type variable in your Cougar class. You are using the same 'type' variable if the super class in go() method/function and setting it to "c". This is the reason you are getting 'c c' in the output.
Make Cougar as below. The syntax is C#.
public class Cougar : Feline
{
public String type = "c";
public Cougar()
{
Console.Write("cougar ");
}
static void Main(String[] args)
{
new Cougar().go();
}
private void go()
{
Console.Write(this.type + " " + base.type);
}
}

T and inheritance in Java

I have a class A with static field F:
class A {
public static String F = null;
}
Class B:
class B extends A {
public static String F = "somestring";
}
and a typed class with a method that uses field F:
class C<T extends A> {
public void someMethod() {
String someString = T.F;
// Manipulations with someString
}
}
And then my code that calls it.
C<B> c = new C<B>();
c.someMethod();
and I'm getting a null pointer exception when trying to manipulate with someString. So, the T.F is null, but T is B, so it should be "somestring"! Why?
You can't Override fields. Since it is extends A, it will always use the field in A.
Add a getter in class A and B that returns F. From there, Override the method in A with the one in B.
class A {
public String getF(){
return null;
}
}
class B {
#Override
public String getF(){
return "someString";
}
}
This doesn't have to do with generics.
The fields of a class cannot be overridden by a subclass - only methods can. So, even if you define a field in your subclass with the same name as the one in the superclass, you're merely creating a new field that simply happens to have the same name but actually shadows (not overrides) the previous one.
Consider putting an assignment with the default value of the field in the constructor of your subclass. Then it should work.
A static member in Java can be hidden, but not overridden. A reference to a static member is resolved at compile time - and at compile time, the only known type of T is A.
See http://www.coderanch.com/how-to/java/OverridingVsHiding.
Edit: A field cannot be overridden anyway, whether it is static or instance.
This happens because all the static members of A are common to A alone and cannot be inherited by B.
No new static member, which is not present in A, can be present in B.
Virtually, when you say
class C < T extends A > {
...
}
You can only use methods(both static and instance - unless #Overriden) and fields which are common in A. So, since F is not an instance field, it is not overriden and the JVM finds the occurance of F in A.
Hence you get an NPE.

Categories

Resources