Java 和 C++ 中,子类继承父类可以重写父类的方法,这种重写称为函数覆盖或者方法覆盖。子类重写父类方法后,可以根据需求修改方法的实现,但也可能会带来访问权限方面的变化。Java 和 C++ 中,子类对父类函数覆盖的可访问性缩小的区别在以下两个方面。
1. 访问修饰符限制
在Java中,函数覆盖必须保证子类方法的访问修饰符不低于父类方法的访问修饰符。也就是说,如果父类方法的访问修饰符是 public,子类方法的访问修饰符只能是 public 或者 protected,不能是 private 或者没有修饰符。
以下是一个Java示例说明:
class Animal {
public void makeSound() {
System.out.println("Animal is making sound.");
}
}
class Cat extends Animal {
// 编译错误,无法重写父类makeSound方法
private void makeSound() {
System.out.println("Cat is making sound.");
}
}
class Dog extends Animal {
// 正确重写父类makeSound方法
public void makeSound() {
System.out.println("Dog is making sound.");
}
}
在上面的代码中,Animal是父类,Cat和Dog是Animal的子类。Cat的makeSound方法访问修饰符是 private,因此编译会报错,无法重写Animal中的makeSound方法。而Dog的makeSound方法访问修饰符是 public,因此可以正确重写Animal中的makeSound方法。
在C++中,子类重写父类的方法时可以缩小访问权限。也就是说,子类方法的访问修饰符可以低于或者等于父类方法的访问修饰符。这就导致如果父类方法是 public,子类方法可以是 public、protected 或者 private。
以下是一个C++示例说明:
class Animal {
public:
virtual void makeSound() {
cout << "Animal is making sound." << endl;
}
};
class Cat : public Animal {
private:
void makeSound() {
cout << "Cat is making sound." << endl;
}
};
class Dog : public Animal {
public:
void makeSound() {
cout << "Dog is making sound." << endl;
}
};
在上面的代码中,Animal是父类,Cat和Dog是Animal的子类。在Cat中,makeSound方法的访问修饰符是 private,可以缩小访问权限,因此可以重写Animal中的makeSound方法。在Dog中,makeSound方法的访问修饰符是 public,同样可以正确重写Animal中的makeSound方法。
2. 返回值类型限制
在Java中,如果子类重写了父类的方法,那么子类方法的返回值类型必须与父类方法的返回值类型一致,或者是其子类,不能是其父类。这个约束被称为协变返回类型。
以下是一个Java示例说明:
class Animal {
public Animal makeSound() {
System.out.println("Animal is making sound.");
return new Animal();
}
}
class Cat extends Animal {
// 编译错误,返回类型不能是 Animal
public Animal makeSound() {
System.out.println("Cat is making sound.");
return new Animal();
}
// 正确重写makeSound方法
public Cat makeSound() {
System.out.println("Cat is making sound.");
return new Cat();
}
}
在上面的代码中,Animal是父类,Cat是Animal的子类。Animal中的makeSound方法的返回类型是 Animal。在Cat中,如果重写Animal中的makeSound方法,返回类型只能是 Cat 或者 Cat的子类,不能是Animal。
在C++中,子类重写父类的方法时,返回值类型的约束更宽松。子类方法的返回值类型可以是和父类方法的返回值类型一致,也可以是其子类或者其父类,C++中不存在Java中的协变返回类型限制。
以下是一个C++示例说明:
class Animal {
public:
virtual Animal* makeSound() {
cout << "Animal is making sound." << endl;
return new Animal();
}
};
class Cat : public Animal {
public:
// 子类返回类型可以是Animal或者他的子类,正确重载了父类方法
virtual Cat* makeSound() {
cout << "Cat is making sound." << endl;
return new Cat();
}
};
在上面的代码中,Animal是父类,Cat是Animal的子类。Animal中的makeSound方法的返回类型是 Animal 。在Cat中,重写Animal中的makeSound方法时,返回类型可以是 Cat ,Animal * 或者其它Animal的子类的指针类型。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java、C++中子类对父类函数覆盖的可访问性缩小的区别介绍 - Python技术站