- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在两个单独的文件中有以下代码。
package animal;
public class Frog
{
protected void ribbit()
{
System.out.println("In Frog class!");
}
}
package other;
import animal.*;
public class Tadpole extends Frog
{
protected void ribbit()
{
System.out.println("In Tadpole class!");
}
public static void main(String[] args)
{
Tadpole t = new Tadpole();
t.ribbit();
Frog f = new Tadpole();
f.ribbit(); // Does not compile
}
}
分配给 Tadpole
类型的第一个 Tadpole
对象显然可以正常编译,并且对 ribbit()
的调用将针对 Tadpole
的 ribbit()
实现。创建并分配给 Frog
引用的第二个 Tadpole
对象。但是,调用 ribbit()
会导致编译器错误。
我知道如果你在子类中创建一个子类对象并赋值给一个在子类包之外的父类(super class)引用并试图调用父类(super class)方法,这是不允许的。但在这种情况下,自从 Tadpole
对象以来,多态性不应该使对象引用“f”调用 Tadpole
的 ribbit()
方法被分配给它?为什么这会导致编译器错误,为什么这是不允许的?
最佳答案
这与访问protected
类成员的规则有关。参见 this section来自 Java Language Specification 的详细信息,具体来说:
Let C be the class in which a
protected
member is declared. Access is permitted only within the body of a subclass S of C.In addition, if Id denotes an instance field or instance method, then:
If the access is by a qualified name Q.Id or a method reference expression Q :: Id (§15.13), where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
If the access is by a field access expression E.Id, or a method invocation expression E.Id(...), or a method reference expression E :: Id, where E is a Primary expression (§15.8), then the access is permitted if and only if the type of E is S or a subclass of S.
因此在 Frog
的子类中,如果 x
是一个 ,您只能访问 x.ribbit()
Frog
的子类(x
不能声明为 Frog
)。
此限制存在于 protected
成员上,否则,假设 Frog
有一个 protected int
字段:
public class Frog {
protected int a = 1;
...
}
然后可以在 Frog
的子类中定义一个 public
方法:
public class TadPole extends Frog {
public int revealFieldValueOfParent(Frog frog) {
return frog.a; // imagine this was OK
}
}
然后任何其他(不相关的)类都可以通过将 Frog
传递给子类的方法来访问该字段:
public class SomeOtherClass {
public static void main(String[] args) {
TadPole tadpole = new TadPole();
Frog frog = new Frog();
int revealedValue = tadpole.revealFieldValueOfParent(frog);
// print revealedValue
}
}
编辑:
此编译器错误与多态性无关。与对象的实际类型相关的多态性是一个运行时方面,编译器不会尝试在运行时考虑变量 f
是否实际引用 Frog
或蝌蚪
。编译器在这里所做的只是强制执行 protected
修饰符的规则,仅此而已。
编辑 2:
根据下面的评论,revealFieldValueOfParent(Frog frog)
方法实际上会显示 protected
的值,如果我们将其更改为revealFieldValue(TadPole frog)
,但您也可以使用私有(private)成员进行显示技巧(即类似于 getter 方法)。子类真正有责任知道自己在做什么。
关于Java使用父类型的对象引用访问不同包中子类中的 protected 成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31995632/
我正在使用 Make,并且有一个 makefile,它设置了一个变量,该变量的值需要我从父 makefile 覆盖。我尝试在父 makefile 中设置变量并使用 export 将其传递给子 make
全屏运行下面的代码片段并调整屏幕大小以查看最后一行中的图像如何堆叠/环绕。它们直接包裹在下一行的正中央。我希望它们向左环绕。 #instafeed{ text-align: center; } #
我在这个网站上找到了以下 jsfiddle,它 90% 回答了我的查询。 JSFiddle 但是我希望能够在内部 div 上包含边距。我已经尝试修改计算以考虑边距,但如果内部 div 不换行或溢出,我
我有 div(class name:xyz) 在其中插入小的 4 div (class name:ax )。我需要垂直插入前两个 div,第三个应该水平插入第一个,第四个应该垂直插入第三个。但是所有的
我有一些动态添加的 QWidgets,我想在它们发生变化时执行一些任务。 我想我不能使用 connect() 因为我还需要触发更改的 QWidget 的名称。 我如何才能同时查看更改了哪个 QWidg
我想在子操作中生成 HTML head 部分;而该页面还有许多其他子操作。 html head 部分取决于其他操作来确定应包含哪些 js/css 文件。不同的子 Action 可以共享同一个js/cs
我正在构建一个 Angular 7 应用程序。我想获取父 div 中某个 div 的“索引”或行。 我的标记如下所示: 我知道如果标记如下所示,我可以轻松做到这一点,但如果
如果我在 Ruby 中调用系统方法,它将在子 shell 中执行我的命令并输出它可以输出的所有内容。因此,如果我将其放入 file.rb 中: system 'vim' 然后运行 $ ruby
我可以对齐两个 div只需设置他们的 display至 inline-block并使用相同的 line-height如下图所示: 但是,我想要的是根据内部 div 的基线对齐两个嵌套 div,如下所示
我的父 Controller 上有一些属性,我希望我的子 Controller 可以访问这些属性。 我想像这样访问它: App.ApplicationController = Ember.Object
我有一个容器 div,里面有一个 SVG: 以及以下 CSS: svg { width: 100%; height: 1
我必须处理的事件目录是这样布置的:域包含许多 OU。这些 OU 之一被命名为“主 OU”。在这个 OU 中,有几个以全局办事处位置命名的 OU(即“芝加哥”“巴黎”)。 任何实际有血有肉的用户帐户都被
我在 NSBox 中有一个 NSTextView。我想每当 NSTextView 获得焦点时在 NSBox 周围绘制焦点环,并在 NSTextView 失去焦点时立即删除焦点环。 谢谢 最佳答案 为此
在下面的代码中,我有一个链接,其 div id 是“my-acc-hover-container”。当用户将鼠标悬停在该链接上时,一个新的部分将向下滑动,其中包含“Hello Guest”和“Logi
我正在使用 javafx 创建一个像 sqlyog 这样的应用程序。我的问题是我想添加数据库。无论何时添加,它都应该更新具有所有其他数据库的 TreeView 。出现创建数据库的对话框,给出名称并设置
我的 UIScrollView 中有几个屏幕的内容,它只能垂直滚动。 我想以编程方式滚动到包含在其层次结构中某处的 View 。 UIScrollView 移动以便 subview 位于 UIScro
我想更新已创建端口的 vif_model。我在 CLI 中使用以下命令 neutron port-update --binding:vif_model=avp 如何使用 neutron 的 pyth
我在一个程序中有两个查询。 查询1:我正在尝试在容器 div 的子 div 内水平对齐两个子 super 子分区。下面是我的代码,你能帮我解决这个问题吗?我已附上所需的输出。 查询2:从代码中你可以看
我在一个程序中有两个查询。 查询1:我正在尝试在容器 div 的子 div 内水平对齐两个子 super 子分区。下面是我的代码,你能帮我解决这个问题吗?我已附上所需的输出。 查询2:从代码中你可以看
我是一名优秀的程序员,十分优秀!