Spedwards
Spedwards

Reputation: 4492

Java Abstraction and Interfaces

It's been a rather long time since I've messed around with Java Abstraction and/or Interfaces, but I'm coming back to it now for a project and something is getting on my nerves. Below is a snippet of my code.

public class A {

    private static String name = "None";
    private static String description = "No description";

    public A() {}

    public A(User user) {
        user.setData(this);
    }

    public static String getName() {
        return name;
    }

    public static String getDescription() {
        return description;
    }

}

public class B extends A {

    private static String name = "B";
    private static String description = "This is B";

    public B() {}

    public B(User user) {
        super(user);
    }

}

public class User {

    private A a;

    public void setData(A a) {
        this.a = a;
    }

    public A getData() {
        return a;
    }

}

When I use B.getName() I expect it to return "B" but it's instead returning "None".

Now I'm obviously doing something wrong, and searching around didn't help a bit. I'm fairly positive that this is possible someway, unless I'm getting confused with another language.

Could someone please point me in the right direction? Thanks.

Upvotes: 1

Views: 143

Answers (6)

Neha Vari
Neha Vari

Reputation: 492

This is the expected behavior since getName() method of class A has access to member variable of its own class that is "name" of class A. It is NOT because of name is static even if you make it non-static and you access it as shown in below code snippet it would return "None". Remember that only methods get overridden not member variables. So "name" of class B is not overriding "name" of class "A".

    B b = new B();
    System.out.println(b.getName()); --> "None" ("name" is non-static)
  ----------------------------------------------
    System.out.println(B.getName()); --> "None"  ("name" is static)

Also, if you want to get "B" as output , override getName() method of class A in class B and make method and variable non-static.

Upvotes: 0

Nathan Hughes
Nathan Hughes

Reputation: 96394

You called the getName method on the class B. B doesn't have a static method called getName, so it looks for it in the superclass, A, which does.

Maybe you expect B's version of name to override A's? Variables don't get overridden. A is accessing the static variable name defined on A, that the method was originally called on B doesn't affect that.

Inheritance and static methods don't work well together. OO concepts like polymorphism rely on runtime dispatching, the word static should imply the opposite of that. With polymorphism the program works at a high level of abstraction, referring to the objects by a super type and letting the subclasses work out the details. With static methods you have to refer to the specific subclass you want the method called on, so you don't have that level of abstraction.

Upvotes: 4

shrewquest
shrewquest

Reputation: 551

A couple of things to note in your class :

  1. name and description are static variables in both A and B
  2. getName is a static method in A

static variables are bound to the class and static methods can't be overridden

Upvotes: 0

hotzst
hotzst

Reputation: 7496

The problem you are facing lies in the definition of the methods getName and getDescription: They are defined in class A as static members. This means that even when calling B.getName() the actual call is A.getName() and there the static member variable value of name is set to None.

When thinking about inheritance you have be careful what you declare as static. This has nothing to do with Interfaces or abstract classes.

public class A {

    protected String name = "None";
    protected String description = "No description";

    public A() {}

    public A(User user) {
        user.setData(this);
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

}

public class B extends A {

    public B() {
      name = "B";
      description = "This is B"
    }

    public B(User user) {
        super(user);
    }

}

public class User {

    private A a;

    public void setData(A a) {
        this.a = a;
    }

    public A getData() {
        return a;
    }

}

With the protected keyword you can access the fields from the extending class.

See also:

Upvotes: 0

Lorenzo Murrocu
Lorenzo Murrocu

Reputation: 688

You need to override the method getName():

public class B extends A {

    private static String name = "B";
    private static String description = "This is B";

    public B() {}

    @Override
    public static String getName() {
        return name;
    }

    public B(User user) {
        super(user);
    }

}

Upvotes: 0

sauumum
sauumum

Reputation: 1788

Welcome back to Java again. You are using static variable in class A and B. These variables are associated with class instead of the objects.

If you change your method to get name from the User, it will work as you are expecting.

Upvotes: 2

Related Questions