Java 为什么从类外访问受保护的成员?

Java 为什么从类外访问受保护的成员?,java,inheritance,Java,Inheritance,我正在创建以下类层次结构: abstract class Shape{ protected abstract float getArea(); protected abstract float getVolume(); } abstract class TwoDimentionalShape extends Shape{ public abstract float getArea(); protected float getVolume(){ r

我正在创建以下类层次结构:

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());
    }
}
我想做的是隐藏
twodmentialshape
类的函数
getVolume()
,因为它将用于
twodmentialshape


问题是我已将函数声明为受保护,但当我从
main()
调用它时,程序正在工作。为什么会发生这种情况?

在包内或包外的子类以及同一包中的类中可见受保护的。看起来您的类都在同一个包中。这就是为什么你能看到它

一般来说,等级制度是:

公共-在所有包和子类中可用

受保护-在子类和相同包中可用

(默认ie nothing)在同一软件包中可用

私有-在同一类中可用

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

我认为这个问题的第一个答案很好地解释了这一点
在包内或包外的子类以及同一包中的类中可见受保护。看起来您的类都在同一个包中。这就是为什么你能看到它

一般来说,等级制度是:

公共-在所有包和子类中可用

受保护-在子类和相同包中可用

(默认ie nothing)在同一软件包中可用

私有-在同一类中可用

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

我认为这个问题的第一个答案很好地解释了这一点
受保护的成员
可以通过
类的子类访问
,该类的受保护的成员位于包之外…..,
继承法则

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


如果在子类的
Square
相同包中有另一个类没有扩展
TwodimensionalShape
类,那么对于该类,方法
getVolume()
将不可见。。。我的意思是
getVolume()
方法将像它的私有成员一样,它看不见。

受保护的成员可以
类的子类访问,该类的子类将受保护的成员放在包之外

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

如果在子类的
Square
相同包中有另一个类没有扩展
TwodimensionalShape
类,那么对于该类,方法
getVolume()
将不可见。。。我的意思是
getVolume()
方法就像它的私有成员一样,它看不到

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

这不是正确的方式。通常,超类声明/定义所有子类通用的方法。如果任何方法不应该出现在子类中,那么它应该是超类的私有方法。如果方法对于某些子类来说是公共的,但是在其他子类中是有意义的,那么它可能不属于这些子类,应该在继承继承继承权的某个地方声明/定义

并非所有的
形状都有体积

protected abstract float getVolume()

不适合
形状
。最好将其从
形状
中删除,并在一个(如
三维形状
)中声明,该形状表示可以具有体积的
形状

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

这不是正确的方式。通常,超类声明/定义所有子类通用的方法。如果任何方法不应该出现在子类中,那么它应该是超类的私有方法。如果方法对于某些子类来说是公共的,但是在其他子类中是有意义的,那么它可能不属于这些子类,应该在继承继承继承权的某个地方声明/定义

并非所有的
形状都有体积

protected abstract float getVolume()


不适合
形状
。最好将其从
形状
中删除,并在一个(如
三维形状
)中声明它,该形状表示可以具有卷的
形状。

受保护的成员和方法在包和继承层次结构中具有访问权限。由于二维空间没有体积,所以应该删除该方法

为3个或更多维度添加
getVolume()
方法


Shape
中添加
getVolume()
方法相当于在
Person
类中添加
getDesignation()
方法,其中
getDesignation()
应位于
Employee
类中,该类扩展了
Person

受保护的成员和方法在包和继承层次结构中的访问权限。由于二维空间没有体积,所以应该删除该方法

为3个或更多维度添加
getVolume()
方法

添加
getVolume()
methodi
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
    }
}
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};
    }
}