rpat
rpat

Reputation: 279

Java - reducing visibility - member data vs member functions

I am just curious about this. I may not be getting this right. However, it appears to me that Java allows reducing visibility for data members but not for member functions. I have a Parent class with a public data member and a public function. If I go to reducing the visibility of a member function in Child class, it is disallowed. When I reduce the visibility of the data member though, it does not complain.

  1. Am I understanding this correctly? If not, where am I wrong?
  2. If so, why is the reduction of visibility for data members allowed?

Here is some code I wrote

class Parent {

    public int dataMember = 20;

    public void function () {
        System.out.println ("Called parent");
    }
}    
public class Child extends Parent {

    private int dataMember = 10;  // Reduces visibility OK

    @Override
    //protected void function () { // Reduces visibility NOT OK
    public void function () {
        System.out.println ("Child class call" );
        System.out.println("Child dataMember = " + dataMember 
                           + " Parent dataMember" + super.dataMember);
    }

    public static void main(String[] args) {

        Child c = new Child ();
        c.function();
        Parent p = new Parent ();
        System.out.println ("Parent data member = " + p.dataMember);
    }

}

The data member can no longer be accessed through the derived class. Is there a way to access the 'dataMember' of the parent class though Child class reference.

public class Another {

    public static void main(String[] args) {

        Child c = new Child ();

        // Cannot access dataMember as expected
        //System.out.println("Child dataMember = " + c.dataMember);

        // Can access dataMember through parent object as expected
        Parent p = new Parent ();
        System.out.println("Parent dataMember = " + p.dataMember);

    }
}

Upvotes: 0

Views: 427

Answers (4)

Software Engineer
Software Engineer

Reputation: 16140

You can't reduce the visibility of an overridden method -- that's the law. If your parent says that you'll perform a service, then you will perform it whether you want to or not. If you don't want to implement this method, then you're inheriting from the wrong class.

Also, it's really not a good idea to declare a variable in a child class with the same name as a variable in a parent class -- this is called shadowing because the child variable is said to cast it's shadow over the parent variable so that it's harder to see.

There are a number of visibility levels in java: private means that nobody can see this thing other than the class it's declared in; protected means that it's declaring class and any derived classes (children) can see it; package (which has no keyword -- you leave the visibility unspecified), which means any class in the declaring package can see it; and public, meaning that any class anywhere can access it.

Upvotes: 0

AllTooSir
AllTooSir

Reputation: 49432

By declaring a new instance variable named x in Child class , you are hiding the super class instance variable x.

Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different.Within the subclass, the field in the superclass cannot be referenced by its simple name. Instead, the field must be accessed through super. Read the tutorials for more information.

You can write a method in class Child as:

public int getParentDataMember() {
    return super.dataMember;
}

And access the member as :

System.out.println("Child dataMember = " + c.getParentDataMember());

Upvotes: 4

Marcin Jedynak
Marcin Jedynak

Reputation: 3847

dataMember member of Child class is hiding your Parent class member, not reducing it's visibility.

You can easily check that. Add the getter to the Child class:

public int getDataMember() { return dataMember; }

And then in the main method:

public static void main(String[] args) {
    Parent p = new Parent();
    System.out.println(p.dataMember); // 10
    Child c = new Child();
    System.out.println(c.getDataMember()); // 20
}

Upvotes: 0

Vaibhav Behl
Vaibhav Behl

Reputation: 36

well we can reduce visibility of variables because using same variable name results in a shadowed variable, unlike in methods() where run time binding occurs..

thus from a parent object you can call a public method (even if it is the instance of child), this would not be possible if the child were allowed to make method private.

Upvotes: 0

Related Questions