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()类。TwoDimentionalShapeThreeDimentionalShape

问题是我已经将该函数声明为受保护的,但是当我从 调用它时main(),程序正在运行。为什么会这样?

4

5 回答 5

4

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

一般来说,层次结构是:

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

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

(默认即没有)在同一个包中可用

私人 - 可在同一个班级

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

我认为这个问题的第一个答案很好地解释了它 在 Java 中,default、public、protected 和 private 之间的区别

于 2012-08-28T18:58:59.327 回答
2

受保护的成员和方法可以访问包和继承层次结构。由于二维没有体积,因此您应该删除该方法。

为 3 维或更大维添加getVolume()方法。

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

于 2012-08-28T19:00:24.293 回答
1

Protected members可以accessed由在包外具有受保护成员的类的子类......,由law of inheritance......

SquaregetVolume()类从其超类继承了方法 TwoDimentionalShape

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

于 2012-08-28T18:59:42.920 回答
0

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

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

并非所有的Shapes 都有音量。

protected abstract float getVolume();

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

于 2012-08-28T19:00:06.710 回答
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};
    }
}
于 2012-08-28T19:10:48.933 回答