在java繼承體系中,認為父類(超類)在上層,子類在下層(派生類) ,
向上轉型就是把子類對象轉成父類對象
向下轉型就是把父類對象轉成子類對象
Person.class
public class Person {
public void work(){
System.out.println("父類。。。");
}
public void study(){
System.out.println("父類...");
}
}
Student.class
public class Student extends Person {
@Override
public void work() {
System.out.println("子類...");
}
public void play(){
System.out.println("子類。。。");
}
}
test.class
public class test {
public static void main(String[] args) {
Person person = new Student();
person.work();
person.study();
//person.play();
((Student) person).play();
//(Student)person.play();
Student student =(Student)person;
student.play();
}
}
>>>子類...
>>>父類...
>>>子類。。。
>>>子類。。。
Person person = new Student(); ----- 向上轉型
向上轉型之後會失去父類中沒有定義的方法,隻能調用父類中定義的方法(子類重寫父類 調用子類的方法)。
是以person.play();無法調用 會爆紅
((Student) person).play();或者Student student =(Student)person; ----- 向下轉型
向上轉型有什麼用處 為何不直接那子類自己定義的對象直接調用?
直接new Student().play();調用也是可以
但是這樣就沒有展現出面向對象的抽象的程式設計思想,而且代碼的可擴充性差。
向下轉型
向下轉型後因為都是指向子類對象,是以調用的當然全是子類的方法~~
向下轉型:轉型時轉的類型必須是父類對象所指的真實子類對象,不是任意的強制類型轉換。
1.正确的向下轉型
Fruit a=new Apple(); //向上轉型
a.myName();
Apple aa=(Apple)a; //向下轉型,編譯和運作皆不會出錯(正确的)
aa.myName();
aa.myMore();
a指向子類的對象,是以子類的執行個體aa也可以指向a啊~~
向下轉型後因為都是指向子類對象,是以調用的當然全是子類的方法~~
2.不安全的向下轉型
Fruit f=new Fruit();
Apple aaa=(Apple)f; //-不安全的---向下轉型,編譯無錯但會運作會出錯
aaa.myName();
aaa.myMore();
f是父類對象,子類的執行個體aaa肯定不能指向父類f啊~~~
3.Java為了解決不安全的向下轉型問題,引入泛型的概念
4.為了安全的類型轉換,最好先用 if(A instanceof B) 判斷一下下~~
總結:
父類引用可以指向子類對象,子類引用不能指向父類對象。
把子類對象直接賦給父類引用叫向上轉型,向上轉型不用強制轉型。
把指向子類對象的父類引用賦給子類引用叫向下轉型,要強制轉型。
向上轉型會丢失子類特有的方法,但是子類overriding 父類的方法,子類方法有效
向上轉型的作用,減少重複代碼,父類作為參數,調用時子類作為參數,就是利用了向上轉型。這樣使代碼變得簡潔。展現了JAVA的抽象面向對象程式設計。
public class Father {
public void eat(){
System.out.println("我是父類的方法吃。。。。。");
}
}
public class Son extends Father{
public void eat(){
System.out.println("我是Son的方法吃。。。。。");
}
public void sleep(){
System.out.println("Son睡覺");
}
}
public class Son1 extends Father {
public void eat(){
System.out.println("son1 的eat方法");
}
public void sleep(){
System.out.println("son1 的sleep方法");
}
}
public class Test {
public static void main(String[] args) {
A(new Son());
A(new Son1());
}
public static void A(Son son){
son.eat();
}
public static void A(Son1 son){
son.eat();
}
}
我的A方法 中需要調用 各個子類的一些或所有方法,代碼如上所示,假若我有很多個子類 這樣 代碼就顯的特别沉于 重複率太高
向上轉型就可以完美的解決此類問題:無論我有多少個子類都可以一個方法搞定
public class Test {
public static void main(String[] args) {
tt(new Son());
tt(new Son1());
}
public static void A(Father son){
//父類對象當做執行個體化參數
son.eat();
}
}