在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();
}
}