继承:子类中方法的可访问性较弱

时间:2014-04-13 23:09:56

标签: java inheritance subclass superclass

在java中需要这样的规则是什么需要:

"子类不能削弱超类中定义的方法的可访问性"

4 个答案:

答案 0 :(得分:2)

含义

子类方法不能比超类方法具有更严格的可见性。

例如,如果超类定义了

protected void a() { } // visible to package and subclasses

子类可以用

之一覆盖它
public void a() { }    // visible to all
protected void a() { } // visible to package and subclasses

但不是

void a() { }           // visible to package
private void a() { }   // visible to itself

为什么

假设定义是

class A {
    public void a() { }
}

class B extends A {
    private void a() { }
}

现在,请考虑以下代码

A instance = new B();
instance.a(); // what does this call? 

一方面,任何B都有一个公开可访问的a方法。另一方面,a实例的B方法只能由B访问。


更一般地说,子类(接口)必须履行其超类(接口)的契约。

可见性只是这一原则的一个例子。另一个例子是非抽象类必须实现它实现的任何接口的所有方法。

答案 1 :(得分:2)

如果您的班级有公共方法

public class Foo {
    public void method() {}
}

此方法可以访问,因此您可以

Foo foo = new Foo();
foo.method();

如果添加子类

public class Bar extends Foo {
    @Override
    public /* private */ void method() {}
}

如果是private,则无法执行

Foo bar = new Bar();
bar.method();

在此示例中,BarFoo,因此必须能够在预期的任何地方替换Foo

为了满足上述语句,子类不能使可继承成员不易访问。但它可以使它更容易访问。 (这基本上只适用于方法。)

答案 2 :(得分:1)

class Person {
    public String name() {
        return "rambo";
    }
}

// subclass reduces visibility to private
class AnonymousPerson {
    private String name() {
        return "anonymous";
    }
}

使用PersonAnonymousPerson作为参数调用以下方法是合法的。但是,如果方法可见性受到限制,则无法调用name()方法。

class Tester {
    static void printPersonName(Person p) {
        System.out.println(p.name());
    }
}

//ok
Tester.printPersonName(new Person());

此调用是合法的,因为PersonAnonymousPerson,但它必须在方法体内失败。这违反了“类型安全”。

Tester.printPersonName(new AnonymousPerson());

答案 3 :(得分:0)

履行接口合同。我们假设我有一个界面IFlying,如下:

public interface IFlying {
    public void fly();
}

我有一个削弱可访问性的实现:

public class Bird implements IFlying {
    private void fly(){
        System.out.println("flap flap");
    }
}

我现在有一些接受IFlying的库函数,并在其上调用fly。实施是私人的。现在发生了什么?当然,这意味着无法访问fly方法。

因此,可访问性在实现中可能不会受到更多限制。