1. 多態
多態存在的三個必要條件:繼承,重寫,父類引用指向子類對象,
當使用多態方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則error;如果有,調用子類的同名方法。
package demo;
public class people {
public people(){
}
public void run(){
System.out.println("10");
}
}
package demo;
public class player extends people{
player(){
}
@Override
public void run() {
//super.run();
System.out.println("100");
}
public static void main(String[] args) {
people bob = new player();
bob.run();
}
}
輸出結果為100
1.1. 多態的局限性
1.1.1. 不能重寫私有方法
只能重寫public,以及protected權限修飾符修飾的方法,以及如果在同一個包下的defult方法
//: polymorphism/PrivateOverride.java
// Trying to override a private method.
package polymorphism;
import static net.mindview.util.Print.*;
public class PrivateOverride {
private void f() { print("private f()"); }
public static void main(String[] args) {
PrivateOverride po = new Derived();
po.f();
}
}
class Derived extends PrivateOverride {
public void f() { print("public f()"); }
} /* Output:
private f()
*///:~
期望輸出的是public f(),但是父類中的private方法被自動認為是final方法,對子類是屏蔽的,所以不能被重載;所以在這種情況下,子類的f()被當作一個全新的方法。
1.1.2. 不能動態綁定域(類變量成員變量或參數)
動態綁定的只有類,而變量沒有動態綁定
//: polymorphism/FieldAccess.java
// Direct field access is determined at compile time.
class Super {
public int field = 0;
public int getField() { return field; }
}
class Sub extends Super {
public int field = 1;
public int getField() { return field; }
public int getSuperField() { return super.field; }
}
public class FieldAccess {
public static void main(String[] args) {
Super sup = new Sub(); // Upcast
System.out.println("sup.field = " + sup.field +
", sup.getField() = " + sup.getField());
Sub sub = new Sub();
System.out.println("sub.field = " +
sub.field + ", sub.getField() = " +
sub.getField() +
", sub.getSuperField() = " +
sub.getSuperField());
}
} /* Output:
sup.field = 0, sup.getField() = 1
sub.field = 1, sub.getField() = 1, sub.getSuperField() = 0
*///:~
所有的域操作都不是多態的,對於子類,域有不同的存儲空間。
1.1.3. 不能重寫私有方法靜態方法
靜態方法屬於類,不能被重寫
1.2. 子類重寫父類方法調用父類方法
在c++中,可以通過向上提升的類型操作實現對父類行為的調用,而在Java中,無論對其進行什么樣的類型轉換,其類型實際上是不變的,只能通過super調用。
example:
package demo;
public class people {
public people(){
}
public void run(){
System.out.println("10");
}
}
package demo;
public class player extends people{
player(){
}
@Override
public void run() {
super.run();
System.out.println("100");
}
public static void main(String[] args) {
people bob = new player();
bob.run();
}
}
1.3. 多態示例1:
函數參數實現多態性
public class people {
public people(){
}
public void run(){
System.out.println("10");
}
}
public class player extends people{
player(){
}
@Override
public void run() {
//super.run();
System.out.println("100");
}
}
public class running {
public void competition(people p1,people p2){//父類引用指向子類對象
p1.run();
p2.run();
}
public static void main(String[] args) {
people bob = new player();
people sam = new player();
running round1 = new running();
round1.competition(bob,sam);
}
}
1.4. 多態示例2:
接口實現多態性,解耦
public interface runrunrun {
public void run();
}
public class people implements runrunrun {
public people(){
}
public void run(){
System.out.println("10");
}
}
public class player implements runrunrun{
player(){
}
//@Override
public void run() {
//super.run();
System.out.println("100");
}
}
public class running {
public void competition(runrunrun p1,runrunrun p2){
p1.run();
p2.run();
}
public static void main(String[] args) {
player bob = new player();
player sam = new player();
running round1 = new running();
round1.competition(bob,sam);
}
}