我展示的是我写的例子,这是因为我不理解java puzzlers中的一些事情:
public class A {
public A foo() {return new A();}
}
package library;
public class C extends A {
static class X extends A {}
@Override
public A foo(){
return new X();
}
}
package library;
public class B extends A {
public static class Y extends A { }
@Override
public A foo(){
return new Y();
}
}
package client;
import library.A;
import library.B;
import library.C;
class Client {
public static void main (String[] args){
A b = new B();
A c = new C();
A bb = b.foo();
A cc = c.foo();
cc.hashCode(); // for me, it should causes compile error
}
}
如您所见,foo
方法是公开的。
A cc = c.foo();
- cc
是非公开类型X
的实例
A bb = b.foo();
- bb
是公共类型Y
因此,当我们调用cc.hashCode()
时,我们从来自不同包的非公共类型调用公共方法。为什么这是正确的?
为什么我这么认为?
在java puzzlers的书中我找到了:
您无法合法地从另一个成员访问非公开类型的成员 封装
此外,
如果使用反射,可以避免这一整类问题 仅用于实例化并使用接口来调用方法 实现它们的类,并提供高级别的类型安全性。
任何人都可以解释一下吗?这在人类语言中意味着什么?
答案 0 :(得分:1)
任何人都可以解释一下吗?这在人类语言中意味着什么?
说明:
Java Puzzlers的书可能指的是其他东西。 (但谁知道:你还没有给我们上下文。)
Java Puzzlers一书并非旨在成为Java语言的规范,教科书或教程。因此,我们不应该尝试使用它......我们不应将其解释视为完整或明确。
实际上你可以调用非公共类的方法,如果它们实现或覆盖在公共超类或非公共类的接口中声明的方法。
< / LI> 醇>技术解释是
A cc = c.foo();
正在访问foo()
中声明的A
方法,该方法是public
类。在非公共类中重写foo()
的事实不会使重写方法不可访问。如果确实如此,那将违反可替代性原则,这是使多态性 1 起作用的原则。
或者更简单地说。
c
是A
。A
都有一个foo()
方法。A::foo()
声明可见的任何内容都必须能够在A
的任何实例上查看该方法。1 - 严格来说,我们在这里谈论的是亚型多态性。还有其他种类的多态性以及哪些LSP不适用。