1

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?

Shashank Jain
  • 847
  • 2
  • 10
  • 25

5 Answers5

4

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

Community
  • 1
  • 1
RNJ
  • 15,272
  • 18
  • 86
  • 131
  • `Sorry but protected is used to access outside the package... You are talking of Default access modifier`, which has package level access... Protected members can be inherited and access by its sub-class OUTSIDE THE PACKAGE. – Kumar Vivek Mitra Aug 28 '12 at 19:03
  • okay, so i understood the problem. and to achieve what i wished to achieve, i added exception throw in getvolume of 2DShape. thanks – Shashank Jain Aug 28 '12 at 20:04
2

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.

Nandkumar Tekale
  • 16,024
  • 8
  • 58
  • 85
  • Sorry but protected is used to access outside the package... You are talking of Default access modifier, which has package level access... Protected members can be inherited and access by its sub-class OUTSIDE THE PACKAGE. – Kumar Vivek Mitra Aug 28 '12 at 19:05
  • don't take it in offending way..... but take a look at your answer, inheritance hierarchy can be in same package also...right ??? So u need to mention Outside the package..... – Kumar Vivek Mitra Aug 28 '12 at 19:09
  • As I didn't mention it, it can be anywhere, in same package or outside package :) – Nandkumar Tekale Aug 28 '12 at 19:10
  • i added getVolume method to Shape because I want to store square class object ref in Shape class pointer(or ref). but when i do, i cannot access the function until they are declared in Shape class. Thats why i wished to make getVolume hidden within TwoDimentionalShape but visible in 3d shape – Shashank Jain Aug 28 '12 at 19:54
  • if we want we can do anything but this one really does not make any sense. You are breaking abstraction. If you want to confirm you can ask different question – Nandkumar Tekale Aug 29 '12 at 05:55
1

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.

Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
0

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.

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
0

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};
    }
}
Frank Orellana
  • 1,820
  • 1
  • 22
  • 29