一直觉得自己对访问权限和函数覆写还挺明白的,直到碰见下面这个情况:
有三个类Animal、Dog和Test;Animal和Test在一个包中,Dog在另一个包中;Dog继承了Animal;Animal和Dog中的bark()方法都是protected的。Test中生成一个Animal引用的Dog对象,调用bark()方法的打印结果是dog bark。
我的问题是Dog中的bark()方法不是protected的吗,这时候Test能成功调用Dog的bark()方法吗?package a;
class Animal {
protected void bark(){
System.out.println("animal bark");
}-------------------------------------package b;
import a.Animal;
class Dog extends Animal{
protected void bark(){
System.out.println("dog bark");
}---------------------------------------package a;
import b.Dog;
class Test {
public static void main(String[] args) {
Animal anim = new Dog();
anim.bark();
}
}
有三个类Animal、Dog和Test;Animal和Test在一个包中,Dog在另一个包中;Dog继承了Animal;Animal和Dog中的bark()方法都是protected的。Test中生成一个Animal引用的Dog对象,调用bark()方法的打印结果是dog bark。
我的问题是Dog中的bark()方法不是protected的吗,这时候Test能成功调用Dog的bark()方法吗?package a;
class Animal {
protected void bark(){
System.out.println("animal bark");
}-------------------------------------package b;
import a.Animal;
class Dog extends Animal{
protected void bark(){
System.out.println("dog bark");
}---------------------------------------package a;
import b.Dog;
class Test {
public static void main(String[] args) {
Animal anim = new Dog();
anim.bark();
}
}
我不太明白 向上转型 动态绑定 多态 不是这样吗 为什么不能调用啊?能啊
但是如果
Dog anim = new Dog();
anim.bark();
就会提示bark() has protected access in ...
class Animal {
void bark(){
System.out.println("animal bark");
}-------------------------------------package b;
import a.Animal;
class Dog extends Animal{
void bark(){
System.out.println("dog bark");
}---------------------------------------package a;
import b.Dog;
class Test {
public static void main(String[] args) {
Animal anim = new Dog();
anim.bark();
}
}
这时候Test执行的结果就成了animal bark了,这又如何解释?
Animal dog = new Dog();
dog.bark();
}}class Dog extends Animal { void bark() { System.out.println("dog bark"); }}结果是"animal bark". 因为Animal中的bark()方法是private的, 所以虽然Dog中也有bark()方法, 但并不是继承自Animal. 我们可以把Dog中的bark()方法看成是另一个方法, 它和Animal中的bark()方法没有什么联系, 并未构成多态. 当将变量dog由Dog向上转型到Animal时, 由于原来的bark不是一个多态方法, 在父类Animal中找不到相应的父级版本, 所以它被屏蔽掉了(或者说丢失了). 所以这时dog.bark()实际上调用的是父类实例中的bark().楼主的例子和这个类似, 只不过范围扩大了一级, 由这里的private-default扩大到了default-protected, 但道理是一样的.