我正在创建以下类层次结构:
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());
}
}
我希望隐藏getVolume()
类的TwoDimentionalShape
函数,因为它将用于ThreeDimentionalShape
类。
问题是我已将该函数声明为受保护,但是当我从main()
调用它时,该程序正在运行。为什么会这样?
答案 0 :(得分:4)
受保护在包中的子类中以及同一包中的类之外可见。看起来您的类都在同一个包中。这就是你能看到它的原因。
一般来说,层次结构是:
公开 - 在所有包和子类中都可用
受保护 - avaialbe在子类和相同的包中
(默认即没有)在同一个包中可用
私人 - 在同一个班级中可用
可以访问(使用反射)一些您通常无法“看到”的字段/方法,尽管这不能保证并且取决于使用的安全管理器。
我认为这个问题的第一个答案很好地解释了这一点 In Java, difference between default, public, protected, and private
答案 1 :(得分:2)
受保护的成员和方法可以在包和inheratance层次结构中进行访问。由于二维没有体积,因此您应该删除该方法。
为3个或更多维度添加getVolume()
方法。
在getVolume()
中添加Shape
方法相当于在getDesignation()
类中添加Person
方法,其中getDesignation()
应位于Employee
类中延伸Person
。
答案 2 :(得分:1)
Protected members
可由accessed
由law of inheritance
之外的包含受保护成员的类的子类组成。Square
。 ...
getVolume()
类继承了超类 TwoDimentionalShape
Square
方法
如果 TwoDimentionalShape
的同一个包 >未扩展 getVolume()
类,然后对于该类,方法getVolume()
将不可见...我的意思是{{1}}方法将像私有成员一样,它看不到。
答案 3 :(得分:0)
我想要做的是为TwoDimentionalShape类隐藏函数getVolume(),因为它将用于ThreeDimentionalShape类。
不是正确的方法。通常,超类声明/定义所有子类共有的方法。如果任何方法不应出现在子类中,那么它应该是超类的私有。如果方法对于某些子类是通用的,但在其他子类中有意义,那么它可能不属于那里,应该在继承继承的某个地方声明/定义。
并非所有Shape
都有音量。
protected abstract float getVolume();
不适合Shape
。最好将其从Shape
中删除,然后将其声明为代表ThreeDimentionalShape
可以拥有音量的那个(例如Shape
)。
答案 4 :(得分:0)
你应该改变你的类树,不要在Shape类中包含方法定义,因为不是每个形状都有一个卷(甚至可能)
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
}
}
现在您可以创建一个3D类:
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};
}
}