Resolution of overriding instance variable in java [duplicate] - java

This question already has answers here:
Overriding member variables in Java ( Variable Hiding)
(13 answers)
Closed 5 years ago.
I know that when you overload method then java resolves it on compilation stage so that's why when you writing something like this:
public class SomeClass{
private static void someMethod(Object obj){
System.out.println("obj");
}
private static void someMethod(String str){
System.out.println("str");
}
public static void main(String[] args) {
Object obj = new SomeClass();
obj.someMethod(obj);
}
}
you will get obj, because oveloading is resolved on compilation and doing something like that:
public abstract class Animal {
public void careFor() {
play();
}
public void play() {
System.out.println("pet animal");
}
}
public class Lion extends Animal {
public void play() {
System.out.println("toss in meat");
}
public static void main(String[] args) {
Animal animal = new Lion();
animal.careFor();
}
}
you will get toss in meat beacuse overriding method is resolved on runtime stage.
But what I don't understand. Why when you overrding instance variable you will get situation like resolving on compilation stage. For example:
public abstract class Animal {
String name = "???";
public void printName() {
System.out.println(name);
}
}
public class Lion extends Animal {
String name = "Leo";
public static void main(String[] args) {
Animal animal = new Lion();
animal.printName();
}
}
In this situation I will get ??? . So it looks like resolving on compilation stage when you overriding variable. Is it so?

In Java Only methods are Polymorphism and not variables.
So when you do
Animal animal = new Lion();
You get all the variables from Animal and methods from Lion gets execute.

Related

No enclosing instance of type 'Abstraction' is accessible

I am getting this No enclosing instance of type 'Abstraction' is accessible problem while trying an abstraction class .
public static void main(String[] args) {
Horse h = new Horse(); //getting problem here`enter code here`
h.walk();
}
abstract class Animal {
abstract void walk();
}
class Horse extends Animal {
void walk() {
System.out.println("Walks on 4 legs");
}
}
can anyone please help me to solve this problem
Animal is declared as an inner class, which means it must be instantiated using an instance of the enclosing class (which you have not shown).
Change Animal and Horse to be static classes.
public static void main(String[] args) {
Horse h = new Horse();
h.walk();
}
static abstract class Animal {
abstract void walk();
}
static class Horse extends Animal {
void walk() {
System.out.println("Walks on 4 legs");
}
}

Why can I access overridden subclass methods from the superclass? [duplicate]

This question already has answers here:
Java superclass calls subclass method
(5 answers)
Closed 1 year ago.
Why does method() call the overridden subclass method2 instead of method2 in the BaseClass?
public class BaseClass {
public void method(){
System.out.println("method() called");
method2();
}
public void method2(){
System.out.println("method2() called");
}
}
public class ChildClass extends BaseClass {
public void method2(){
System.out.println("method2() from BaseClass");
}
}
public class Main {
public static void main(String[] args) {
ChildClass obj = new ChildClass();
obj.method();
}
}
This is the concept of Runtime polymorphism (Dynamic Method Dispatch). Because you are assigning the object (instance) of ChildClass to obj reference variable, it will call the method of child class.
Always the method of the class whose instance is created gets called first. If that method is not present in that particular child class, then the parent's inherited method gets called.
If you come from the C++ corner:
all instance methods (non-static) in Java are virtual.
All class methods (static) are NOT.
This is why your case happens.
This is also, why the Java compiler will complain (warn) that if you access a static method via an object, that you should call via the distinct class, because calls to the "static method of a object" could be ambiguous, because it could be two static methods with the same signature that get called.
Extending your Example:
package stackoverflow.staticcalls;
public class BaseClass {
public void method() {
System.out.println("method() called");
method2();
}
public void method2() {
System.out.println("method2() called");
}
static public void sayHello() {
System.out.println("BaseClass.sayHello()");
}
}
and
package stackoverflow.staticcalls;
public class ChildClass extends BaseClass {
public void method2() { // compiler warning: The method method2() of type ChildClass should be tagged with #Override since it actually overrides a superclass method
System.out.println("method2() from BaseClass");
}
public void originalCallToBaseMethod2() {
super.method2(); // will run BaseClass.method2()
}
static public void sayHello() {
System.out.println("ChildClass.sayHello()");
}
}
and
package stackoverflow.staticcalls;
public class Main {
public static void main(final String[] args) {
final ChildClass obj = new ChildClass();
System.out.println("\nCalling obj.method(); ...");
obj.method();
System.out.println("\nCalling obj.sayHello(); ...");
obj.sayHello(); // compiler warning: The static method sayHello() from the type ChildClass should be accessed in a static way
System.out.println("\nCalling ChildClass.sayHello(); ...");
ChildClass.sayHello(); // the proper call
System.out.println("\nCalling BaseClass.sayHello(); ...");
BaseClass.sayHello(); // but you can also explpicitly call the other method
System.out.println("\nCalling obj.originalCallToBaseMethod2(); ...");
obj.originalCallToBaseMethod2(); //
}
}
Here you see the examples to what I said.
Note: In the last call in Main.main() we still can call BaseClass.method2(), but not directly. We have to be within ChildClass to do that, and it's done via the super keyword/reference.
A little off-topic note, to complete addressing patterns:
If you're inside an inner class and need to call to a overshadowed name in the outer class, you can use Outer.this.method():
package stackoverflow.staticcalls;
import stackoverflow.staticcalls.OuterInner.Outer.Inner;
public class OuterInner {
class Outer {
void method() {
System.out.println("OuterInner.Outer.method()");
}
class Inner {
void method() {
System.out.println("OuterInner.Outer.Inner.method()");
}
void callOuter() {
Outer.this.method();
}
}
}
public static void main(final String[] args) {
final OuterInner oi = new OuterInner();
final Outer outer = oi.new Outer();
final Inner inner = outer.new Inner();
System.out.println("\nCalling inner.method(); ...");
inner.method();
System.out.println("\nCalling inner.callOuter(); ...");
inner.callOuter();
}
}

Overriding an anonymous class's methods in Java

In below example (in the commented block) I'm trying to override jump() method of an anonymous class, however getting compilation error. Can someone help me understand what's wrong here?
class Animal {
public void bark() {
System.out.println("Inside bark");
}
public void jump() {
System.out.println("Inside jump");
}
}
public class AnonymousClassExample001 {
public static void main(String[] args) {
Animal animal = new Animal() {
public void bark() {
System.out.println("Subclass bark");
}
}; /* {
public void jump() {
System.out.println("Subclass jump");
}
};*/
/**
* Question is: Why can't we override by extending an anonymous class
* as attempted (and commented) above?
* */
animal.bark(); // Subclass bark
animal.jump(); // Trying to print "Subclass jump", by overriding (the subclass of Animal) above
}
}
Edit:
Here's the compilation error I'm getting in IDE - ';' expected.
And from the comments, it seems some folks are not getting my question. With the above example, I wanted to understand whether we can override an anonymous class's methods or not?.
Again, the main motive is to see (and understand) why Java compiler allowed to create an anonymous class by starting a {} block followed by new Animal(), and didn't allow the same behaviour further (chaining of {} blocks to allow creation of further subclasses)
Don't end and restart the block, override both methods in one block, same as you would in a regular subclass:
class AnonymousClassExample001 {
public static void main(String[] args) {
Animal animal = new Animal() {
#Override
public void bark() {
System.out.println("Subclass bark");
}
#Override
public void jump() {
System.out.println("Subclass jump");
}
};
animal.bark(); // Subclass bark
animal.jump(); // Subclass jump
}
}
UPDATE
Updates to the question says you're trying to subclass an anonymous class, e.g. you're trying to do this:
class AnonymousClassExample001 {
public static void main(String[] args) {
Animal barkingAnimal = new Animal() {
#Override
public void bark() {
System.out.println("Subclass bark");
}
};
Animal jumpingAnimal = <subclass barkingAnimal> { // Can't be done
#Override
public void jump() {
System.out.println("Subclass jump");
}
};
barkingAnimal.bark(); // Subclass bark
barkingAnimal.jump(); // Inside jump
jumpingAnimal.bark(); // Subclass bark
jumpingAnimal.jump(); // Subclass jump
}
}
You can't do that, because the unnamed anonymous class cannot be identified as the base class. You can however do it using local classes, which are like named anonymous classes, as contradictory as that sounds:
class AnonymousClassExample001 {
public static void main(String[] args) {
class BarkingAnimal extends Animal {
#Override
public void bark() {
System.out.println("Subclass bark");
}
};
class JumpingAnimal extends BarkingAnimal {
#Override
public void jump() {
System.out.println("Subclass jump");
}
};
Animal barkingAnimal = new BarkingAnimal();
Animal jumpingAnimal = new JumpingAnimal();
barkingAnimal.bark(); // Subclass bark
barkingAnimal.jump(); // Inside jump
jumpingAnimal.bark(); // Subclass bark
jumpingAnimal.jump(); // Subclass jump
}
}
Alternatively, jumpingAnimal could also be done using anonymous class syntax, instead of local class syntax.
I think it should be like this
public class AnonymousClassExample001 {
public static void main(String[] args) {
Animal animal = new Animal() {
public void bark() {
System.out.println("Subclass bark");
}
public void jump() {
System.out.println("Subclass jump");
}
};
/**
* Question is: Why can't we override by extending an anonymous class
* as attempted (and commented) above?
* */
animal.bark(); // Subclass bark
animal.jump(); // Trying to print "Subclass jump", by overriding (the subclass of Animal) above
}
}

I'm not sure why this code isn't compiling, it requires a non-static variable [duplicate]

This question already has answers here:
What does the 'static' keyword do in a class?
(22 answers)
Closed 4 years ago.
class TheAnimal {
public class Animal {
void bark(){
System.out.println("Woof-Woof");
}
}
public static void main(String[] args){
Animal dog = new Animal();
dog.bark();
}
}
// Keeps saying on line 12 Animal dog = new Animal(); after compiling that it's a non-static variable and that it cannot be referenced from a static context.
You created an inner class Animal which can only be instantiated in a outer class instance context (which is probably not what you want/need now). Declare your inner class as static will let you instanciated it as you think:
class TheAnimal {
static public class Animal {
void bark(){
System.out.println("Woof-Woof");
}
}
public static void main(String[] args){
Animal dog = new Animal();
dog.bark();
}
}
You inner class Animal requires an instance of TheAnimal, make it static.
public static class Animal {
void bark(){
System.out.println("Woof-Woof");
}
}
Or, you need an instance of TheAnimal in main. Like,
public static void main(String[] args) {
Animal dog = new TheAnimal().new Animal();
dog.bark();
}

Polymorphic arguments work with superclass but not with subclass [duplicate]

This question already has answers here:
What does a "Cannot find symbol" or "Cannot resolve symbol" error mean?
(18 answers)
Closed 5 years ago.
I am only learning about polymorphism so be easy on me (literally copying from the book). I try to pass a class as an argument to a method. When I do that I can call the superclass methods, but not the actual subclass. Using the start() method, I try to make the wolf howl:
public class experiment {
public static void main(String[] args) {
PetOwner own = new PetOwner();
own.start();
}
}
//Trying polymorphic arguments
class Vet {
public void giveShot(Animal a) {
a.howl();
}
}
class PetOwner {
public void start() {
Vet v = new Vet();
Wolf w = new Wolf();
v.giveShot(w);
}
}
//Inheritance//
//Kingdom - Animal
class Animal {
public void move() {
System.out.println("*motions softly*");
}
}
//Family - canine
class Canine extends Animal {
public void bark() {
System.out.println("Woof!");
}
}
//Species - wolf
class Wolf extends Canine {
public void howl() {
System.out.println("Howl! Howl!");
}
}
If I pass the howl method to the superclass (Animal) it works fine. If I call it directly from the Wolf class - it works fine. The only instance where it doesn't work is if I try to pass the wolf class as an argument and call it from there.
Here is why I try it that way, quoted from Head First Java pg 187:
The Vet's giveShot() method can take any Animal you give it. As long
as the object you in as the argument is a subclass of Animal, it
will work
I am getting a "cannot find symbol symbol: method howl(), Location variable of type animal" error.
You're calling a.howl() while a is an instance of Animal class. Animal does not know how to howl. The only Wolf does.
You can defin a method say react() and then override it for any particular subclass of Animal;
You are calling the howl-Method inside the giveShot-Method. Animal doesn't have a howl method.
EDIT: If you cast animal to wolf inside the giveShot-Method it should work.
Yes, you could do something like:
class Vet {
public void giveShot(Animal a) {
a.makeNoise();
}
}
class Animal {
public void move() {
System.out.println("*motions softly*");
}
public void makeNoise() {
}
}
//Family - canine
class Canine extends Animal {
#Override
public void makeNoise() {
System.out.println("Woof!");
}
}
//Species - wolf
class Wolf extends Canine {
#Override
public void makeNoise() {
System.out.println("Howl! Howl!");
}
}

Categories

Resources