2012-08-28 45 views
1

我创建类层次结构:为什么要从外部类访问受保护的成员?

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()调用它时,程序正在工作。这是为什么发生?

回答

4

受保护的软件包中的子类中或软件包外部的子类中都可见。它看起来像你的课都在同一个包。这就是为什么你可以看到它。

一般的层次结构是:

公共 - 在所有的包和子类

可用

保护 - avaialbe子类,并在相同的可用相同的封装

(默认值即无)包

私人 - 可在同一类

可以访问(使用反射)一些通常无法“看到”的字段/方法虽然不能保证,并且取决于所使用的安全管理器。

我觉得这个问题的第一个答案解释得很好 In Java, difference between default, public, protected, and private

+0

'对不起,但保护被用来访问包外...你正在谈论的默认访问修饰符,它具有包级访问...受保护的成员可以继承和访问其子类OUTSIDE包装。 –

+0

是的你是对的。我会更新并使答案更清晰 – RNJ

+0

好,所以我明白了这个问题。为了实现我希望实现的目标,我在2DShape的getvolume中添加了异常。谢谢 –

1

Protected members可以通过子已被保护的成员外面包....之类的是accessed,由law of inheritance .....

Square类继承了getVolume()方法从超类TwoDimentionalShape

如果同一封装的使得子类Square,已经不延长TwoDimentionalShape类的另一类,那么该类的方法getVolume()将是不可见的.. 。我的意思是getVolume()方法将像一个私人成员,它不能看到。

0

我想要做的是隐藏TwoDimentionalShape类的函数getVolume(),因为它将用于ThreeDimentionalShape类。

不正确的路要走。通常,超类声明/定义所有子类通用的方法。如果任何方法不应出现在子类中,那么它应该对超类是私有的。如果方法对某些子类很常见,但在其他子类中有意义,那么它可能不属于那里,应该在继承heirarcy的某个地方声明/定义。

并非所有的Shape有容积。

protected abstract float getVolume();

不适合在Shape。最好将其从Shape中删除,并在代表可以有音量的Shape之一(如ThreeDimentionalShape)中声明。

2

受保护的成员和方法可以访问包和激励层次结构。由于二维没有音量,所以您应该删除该方法。

添加getVolume()方法为3或更大的尺寸。

添加getVolume()方法在Shape相当于Person类,其中getDesignation()应在其延伸PersonEmployee类添加getDesignation()方法。

+0

对不起但受保护的是用于在包外访问...您正在谈论默认访问修饰符,它具有包级别访问权限......受保护的成员可以继承和访问其子类“外包”。 –

+0

我说的是对的,我说继承层次结构 –

+0

不要把它当成冒犯的方式.....但是看看你的答案,继承层次结构可以在同一个包里也可以......对吗?所以你需要提到外包..... –

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}; 
    } 
} 
+0

问题是,当存储引用Sphere对象时,我将无法访问getVolume方法 –

+0

您可以将其投射到: (Sphere)myshape; –

相关问题