Calling methods of super-classes - java

This program is supposed to individually call the funFact of each subclass but instead, it calls the funFact method only from the Mammal class. What am I doing wrong?
public class MammalFacts{
public static class Mammal{
public static String funFact(){
return "If you are reading this, there's a 70% chance you're a mammal";
}//end funFact
}//end mammal
public static class Primate extends Mammal{
public static String funFact(){
return "All primates can fly";
}
}//end Primate
public static class Monkey extends Primate{
public static String funFact(){
return "Monkies will rule the earth someday";
}
}
public static void main(String[]args){
Mammal[]i = new Mammal[3];
i[0] = new Mammal();
i[1] = new Primate();
i[2] = new Monkey();
for(int c = 0; c < i.length; c++){
System.out.println(i[c].funFact());
}
}//end of main
}//end MammalFacts

funFact is static. Overriding doesn't work on static methods.
Remove the static keyword from all your methods (as you are calling them via an instance reference anyway) and it will work as you expected.

If you "override" the static method, you are hiding the method, not really overriding.
read this:
https://docs.oracle.com/javase/tutorial/java/IandI/override.html
the "Static Methods" section exactly answers your question.

Related

Method override not working properly in Java [duplicate]

I have a simple question that I just can't figure out a good answer for. Why does the following Java program display 20? I would prefer a detailed response if possible please.
class Something{
public int x;
public Something(){
x=aMethod();
}
public static int aMethod(){
return 20;
}
}
class SomethingElse extends Something{
public static int aMethod(){
return 40;
}
public static void main(String[] args){
SomethingElse m;
m=new SomethingElse();
System.out.println(m.x);
}
}
Because polymorphism only applies to instance methods.
The static method aMethod invoked here
public Something(){
x=aMethod();
}
refers to the aMethod declared in Something.
The inheritance for static methods works differently then non-static one. In particular the superclass static method are NOT overridden by the subclass. The result of the static method call depends on the object class it is invoke on. Variable x is created during the Something object creation, and therefore that class (Something) static method is called to determine its value.
Consider following code:
public static void main(String[] args){
SomethingElse se = new SomethingElse();
Something sg = se;
System.out.println(se.aMethod());
System.out.println(sg.aMethod());
}
It will correctly print the 40, 20 as each object class invokes its own static method. Java documentation describes this behavior in the hiding static methods part.
Because int x is declared in the class Something. When you make the SomethingElse object, you first make a Something object (which has to set x, and it uses the aMethod() from Something instead of SomethingElse (Because you are creating a Something)). This is because aMethod() is static, and polymorphism doesn't work for static methods. Then, when you print the x from m, you print 20 since you never changed the value of x.

Why are my Java Instance Initializers initializing twice?

I have written a simple code with a super class and two sub classes in order to track order or initialization. My static initializers behave like expected and initialize in the proper order. But my instance initializers seem to run twice before my constructors. I know that's the order of initialization but I'm trying to gain some insight an follow the flow and am lost as to why the instance initializers print twice. Here's my code and the output I receive. (see below)
class Bird{
static {System.out.println("Static Initializer 1");}
{System.out.println("Instance Initializer 1");}
int feathers = 0;
Bird(int x){ this.feathers = x; }
Bird fly() { return new Bird(1); }
}
class Parrot extends Bird {
static {System.out.println("Static Initializer 2");}
{System.out.println("Instance Initializer 2");}
protected Parrot(int y){ super(y); }
protected Parrot fly(){ return new Parrot(2); }
}
public class Macaw extends Parrot {
static {System.out.println("Static Initializer 3");}
{System.out.println("Instance Initializer 3");}
public Macaw(int z){ super(z); }
public Macaw fly(){ return new Macaw(3); }
public static void main(String... args){
Bird p = new Macaw(4);
System.out.println(((Parrot)p.fly()).feathers);
}
}
Results:
Probably because your fly() method literally creates a new instance:
public Macaw(int z){ super(z); }
public Macaw fly(){ return new Macaw(3); } <---- NEW
public static void main(String... args){
Bird p = new Macaw(4); // Instance 1
System.out.println(((Parrot)p.fly()).feathers); // Calling fly() creates instance 2
}

I've got trouble with inner and static inner class at java

Firstly, Thanks everybody that read that topic.
How can if statement become true in test class? I couldnt find any solution.I couldnt write any code in these method.I tried to send from Room class numberOfTiger to class Question's method but I didnt achieve that.
That's question about ,How can I change int variable(numberofTiger) to Cat.Tiger variable.After that if statement become true to invoke (getNumberOfTiger) method.
public class Test {
public static void main(String[] args) {
Animal an = new Animal();
Animal.Cat an1 = an.new Cat();
Animal.Cat.Tiger an2 = an1.new Tiger(3, 900, 2);
if (Animal.Question.getnumberOfTiger(an2) == 3) {
System.out.println("True");
}
}
}
public class Animal {
Cat[] c;
// inner class
class Cat {
Tiger[] t;
// inner class
class Tiger {
private int numberOfTiger;
private int averageOfTigerWeigth;
private int youngTiger;
public Tiger(int numberOfTiger, int averageOfTigerWeigth, int youngTiger) {
super();
this.numberOfTiger = numberOfTiger;
this.averageOfTigerWeigth = averageOfTigerWeigth;
this.youngTiger = youngTiger;
}
static class Question {
static int getnumberOfTiger(Cat.Tiger a) {
return 0;
}
}
}
In addition to either making Cat a static class, or using its instance,
you also need a getter for a.numberOfTiger since it is private, in Tiger class:
public getNumberOfTiger() {
return numberOfTiger;
}
Then:
return a.getNumberOfTiger();
In getNumberOfTiger() you need to return the number of tigers associated with that object. You are currently just returning 0, so it will always evaluate to false.
I see the issue. The Tiger class and the Cat class needs to be static. The reason is, a non-static inner class can call on its outer class (e.g. Cat.this.something). A non-static inner type is called like this:
instanceOfOuterClass.innerClass
whereas a static inner type is called like this:
outerClassName.innerClass
The simplest way to call on a non-static inner type is new Outer().new Inner(); The main issue with beginners in Java is that they try to do this:
new (new Outer()).Inner()
But the actual way to call it is
new Outer().new Inner()
Also, your method is always returning 0 for the count of tigers.

Why can I inherit final method from inner class?

I discovered that following code compiles:
class Ideone
{
public static void main (String[] args){
new Ideone().m();
}
final private void m(){
System.out.println("private final method");
}
class A extends Ideone{
public void method(String [] args){
m();
}
}
}
and executes.
I am very wondering about this.
Can you explain why does java designers(founders) made that it works?
A final method can be inherited by a sub class regardless the sub class is outside the parent class or inside the parent class. But you cannot override the final method in your subclass. If the final method is private you cannot inherit that in your subclass unless your subclass is inside the parent class (like in your example).
Since you declare the method private, then final has no effect and is redundant.
Overriding a private method don't really make much sense.
It is no different then calling a private method in a class from another method in the same class (which might be public). That is something that is done often to keep code more readable and method's manageable in size.
I don't think it is a stupid question :)
Take the Builder-pattern for example. It utilizes private constructors to make sure the class is constructed the correct way. So understanding what you have available in different scope's, and why is important :)
class Ideone {
private String m;
private Ideone(String m) {
System.out.println("Build me with: " + m);
this.m = m;
}
public String getM() {
return m;
}
static class IdeoneBuilder{
String m;
public IdeoneBuilder withM(String m) {
this.m = m;
return this;
}
public Ideone build() {
return new Ideone(this.m);
}
}
public static void main (String[] args){
// new Ideone(); // will not compile
Ideone ideone = new IdeoneBuilder()
.withM("test").build();
}
}
Edit: You can make the class Ideone final, and it will still work. And you are also making it impossible to subclass it. In other words, you make sure there is no other way to construct an object of your class other than using the builder (unless the use of reflection).

Inner static classes in java

public interface Bsuper {
abstract class A {
abstract void test1();
void test2() {
System.out.print("test2 ");
}
}
}
// second file
public class Bsub extends Bsuper.A {
void test1() {
System.out.print("test1 ");
}
}
// third file
public class Bsubmain {
public static void main(String args[]) {
Bsub sub1 = new Bsub();
Bsuper.A obj = new Bsub();
sub1.test1();
sub1.test2();
obj.test1();
obj.test2();
}
}
It produces the output as expected test1 test2 test1 test2, but my question is in the Bsuper class, class A is static we all know that and now with the abstract keyword it becomes abstract class, but how is it possible to have both abstract and static applied to class at the same time.Is class A really static also or is there any other explanation for it.Please answer!!
how is it possible to have both abstract and static applied to class at the same time.
It is perfectly valid to have a static abstract class. This is different from having a static abstract method, which doesn't make sense, as you can't override such methods, and you're also making it abstract. But with static class, you can of course extend it, no issues. Making it abstract just restricts you with creating an instance of it.
So, even this is valid:
class Main {
static abstract class Demo { }
class ConcreteDemo extends Demo { }
}
In which case, you can't instantiate Demo, and sure you can instantiate ConcreteDemo.
Remember that a static inner class is using a different concept of static.
In this case it means that the inner class does not have access to the outer class's instance variables.
public class Test {
long n = 0;
static class A {
// Not allowed.
long x = n;
}
class B {
// Allowed.
long x = n;
}
}
Making them abstract does not change anything.
abstract static class C {
// Not allowed.
long x = n;
}
abstract class D {
// Allowed.
long x = n;
}

Categories