Shashank Jain
Shashank Jain

Reputation: 857

Why accessing protected member from outside class?

I am creating following class hierarchy:

abstract class Shape{
    protected abstract float getArea();
    protected abstract float getVolume();
}

abstract class TwoDimentionalShape extends Shape{
    public abstract float getArea();
    protected float getVolume(){
        return 0;
    }
}

class Square extends TwoDimentionalShape {
    float width, height;
    Square(float w, float h){
        width = w;
        height = h;
    }
    public float getArea(){
        return width*height;
    }
}

public class ShapeTest {
    public static void main(String args[]){
        Shape s = new Square(3, 4);
        System.out.println(s.getVolume());
    }
}

What I wish to do is to hide the function getVolume() for TwoDimentionalShape class, as it will be used for ThreeDimentionalShape class.

The problem is that I have declared the function as protected, but when I call it from main(), the program is working. Why is this happening?

Upvotes: 1

Views: 1960

Answers (5)

Nandkumar Tekale
Nandkumar Tekale

Reputation: 16158

protected members and methods has access within the package and inheratance hierarchy. As two dimensional does not have volume, so you should remove that method.

Add getVolume() method for 3 or greater dimensions.

Adding getVolume() method in Shape is equivalent to adding getDesignation() method in Person class, where getDesignation() should be in Employee class which extends Person.

Upvotes: 2

Bhesh Gurung
Bhesh Gurung

Reputation: 51030

What I wish to do is to hide the function getVolume() for TwoDimentionalShape class, as it will be used for ThreeDimentionalShape class.

Not the right way to go. Usually, a superclass declares/defines methods that are common to all the subclasses. And if any of the method should not appear in the subclasses then it should be private to the superclass. And if method is common to some of the subclasses but does make sense in other subclass(es) then it probably does not belong there and should be declared/defined somewhere down the inheritance heirarcy.

Not all the Shapes have volume.

protected abstract float getVolume();

does not fit in Shape. Better to remove it from Shape and declare it in the one (like ThreeDimentionalShape) that represents a Shape that can have volume.

Upvotes: 0

Frank Orellana
Frank Orellana

Reputation: 1898

You should change your class tree and do not include the method definitions in the Shape class since not every shape will have a volume (and even maybe)

public interface class Shape{ //optional but helpful: interface instead of abstract class. not an abstract class but an interface
    public float getArea();  //not abstract, not protected
    //protected abstract float getVolume(); this should not go in here
}

abstract class TwoDimentionalShape implements Shape{ //implement instead of extend. also this can qualify as an interface instead of an abstract class
    public abstract float getArea();
}

class Square extends TwoDimentionalShape {
    float width, height;
    Square(float w, float h){
        width = w;
        height = h;
    }
    /*public float getArea(){  not needed in a twodimensionalshape
        return width*height;
    }*/
}

public class ShapeTest {
    public static void main(String args[]){
        Shape s = new Square(3, 4);
        System.out.println(s.getVolume()); //will not compile
    }
}

and now you can create a 3D class:

abstract class ThreeDimentionalShape implements Shape{
    public abstract float getArea();
    public abstract float getVolume();  //All 3D shapes will have a volume!!
}

class Sphere extends ThreeDimentionalShape {
    float radius;
    Sphere (float radius){

    }
    public float getArea(){  not needed in a twodimensionalshape
        return {place some forgotten formula here};
    }
    public float getVolume(){  not needed in a twodimensionalshape
        return {place some forgotten formula here};
    }
}

Upvotes: 0

Kumar Vivek Mitra
Kumar Vivek Mitra

Reputation: 33534

Protected members can be accessed by the subclass of the class that has the protected member outside the package...., by the law of inheritance.....

Square class has inherited the getVolume() method from its super class TwoDimentionalShape

If there is another class in the same package of that of the sub-class Square, that has not extended the TwoDimentionalShape class, then for that class the method getVolume() would be not visible... i mean the getVolume() method will be like a private member to it, which it can't see.

Upvotes: 1

RNJ
RNJ

Reputation: 15552

Protected is visible in sub classes in or outside of the package and classes in the same package. It looks like your classes are all in the same package. That is why you can see it.

In general the hierachy is:

Public - available in all packages and sub classes

Protected - avaialbe in sub classes and the same package

(Default ie nothing) available in the same package

Private - available in the same class

It is possible to access (using reflection) some fields/methods that you cannot normally "see" although this is not guaranteed and depends on teh security manager that is used.

I think the first answer of this questions explains it very well In Java, difference between default, public, protected, and private

Upvotes: 4

Related Questions