首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么Java不限制子类的可见性大于父类呢

为什么Java不限制子类的可见性大于父类呢
EN

Stack Overflow用户
提问于 2015-12-12 05:18:45
回答 2查看 90关注 0票数 1

为什么可以在Java中创建可见性低于超类的子类?

代码语言:javascript
运行
复制
package 1
public class Class1 {

    public Class1 hello(){
        Class1 c= new Class2();
        return c;
    }   
}


class Class2 extends Class1 {

     public Class1 hello() {
        System.out.println("In overriden method");
            return null;
    }    
}

假设Class1和Class2都在同一个包中,则Class2可见性是包私有的。

代码语言:javascript
运行
复制
package 2
public class Major {
    public static  void main(String[] args) {
        Class1 ob = new Class1();
        ob.hello().hello();
    }
}

您会注意到,由于运行时的多态性,"In overriden method“将被打印出来。

在运行时,当Class2位于包私有可见性的不同包中时,如何从main()访问Class2Class2方法?

Class2不应该是可访问的,因此Class2中的hello()方法也不应该是可访问的。

EN

回答 2

Stack Overflow用户

发布于 2015-12-12 07:08:31

protected关键字(在某种程度上类似于package private)是一种防止代码被外部使用的方法,而这正是在您的示例中发生的事情。您没有直接使用Class2,您使用的是Class1,它授予您间接使用受保护Class2的权限。

这是一个责任原则。public Class1负责授权外部包使用protected Class2。但这种责任也意味着Class1的开发人员必须知道为什么以及如何授予您该权限。

事实是,你的extend Class1在你的例子中没有真正的意义,你的困惑可能来自于此。您不能从包外部实例化Class2,但Class1可以。

票数 0
EN

Stack Overflow用户

发布于 2015-12-15 01:37:46

实际上,考虑到所涉及的方法的类型签名,它可能无法以任何其他方式工作。

Class1声明了一个名为hello的方法,返回一个Class1的对象。因此,该方法返回的内容必须实现与Class1兼容的接口。当Class1.hello()返回一个Class2实例时,调用者与它交互的方式不应该与它是Class1的实例时不同-这是Liskov Substitution Principle的作用-这是关键的面向对象原则之一。

如果Class2.hello()由于Class2被隐藏而变得不可访问,那么调用者将不得不面对这样一个事实:他们不知道Class1.hello()将返回什么类型的对象-有时它可能是Class2的对象,有时可能是Class1的对象,或者任何其他可以从Class1扩展的对象,唯一知道的方法是检查代码-即知道Class1的实现细节。在这种情况下,编译器将无法保证类型安全,因为原则上,Class1.hello()可能是不可确定的或依赖于运行时状态。在静态类型的语言中,这几乎是游戏结束了。

以某种方式隐藏类-通过将其创建为私有类型,通过匿名实现接口,通过反射欺骗等-只是为了隐藏类型本身,而不是它实现的接口。通过扩展另一个类,任何给定类型都会自动继承父类型的接口,包括它的可见性。扩展类型只允许增加接口的可见性,而不允许减少接口的可见性,否则就违反了Liskov替换原则。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34232738

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档