欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

向上、向下转型

程序员文章站 2022-07-10 21:13:41
向上、向下转型基础知识多肽回顾:1.多肽是方法的多肽,不是属性的多肽(多肽与属性无关)。2.多肽的存在有三个必要条件:继承、方法重写、父类引用指向子类对象。3.父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多肽就出现了。一、向上转型原文链接class Animal {public void eat(){System.out.println("父类的 吃...");}}class Bird extends Animal{@Overridepublic v...

向上、向下转型

基础知识多肽回顾:
1.多肽是方法的多肽,不是属性的多肽(多肽与属性无关)。
2.多肽的存在有三个必要条件:继承、方法重写、父类引用指向子类对象。
3.父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多肽就出现了。

一、向上转型

原文链接

class Animal {
	public void eat(){
		System.out.println("父类的 吃...");
	}
}
class Bird extends Animal{	
	@Override
	public void eat(){
		System.out.println("子类重写的父类的  吃吃吃...");
	}	
	public void fly(){
		System.out.println("子类新方法  飞飞飞...");
	}
}
public class Sys{
	public static void main(String[] args) {
		Animal b=new Bird(); //向上转型
		b.eat(); 
		//  b.fly(); b虽指向子类对象,但此时子类作为向上的代价丢失和父类不同的fly()方法
		sleep(new Male());
		sleep(new Female());//传入的参数是子类-----!!
	}
	
	public static void sleep(Human h) {//方法的参数是父类------!!!
 		 h.sleep();
        }
}     
public class Human {
	public void sleep() {
		System.out.println("父类人类   sleep..");
	}
}
class Male extends Human{
	@Override
	public void sleep() {
		System.out.println("男人 sleep..");
	}
}
class Female extends Human {
	@Override
	public void sleep(){
		System.out.println("女人 sleep..");
	}
}

输出:
子类重写的父类的 吃吃吃…
男人 sleep…
女人 sleep…
详解:

  1. 向上转型的实现

        Animal b=new Bird(); //向上转型
        b.eat(); // 调用的是子类的eat()方法
        b.fly(); // 报错!!!!!-------b虽指向子类对象,但此
        时子类作为向上转型的代价丢失和父类不同的fly()方法------
    

2.为何不直接Bird b=new Bird();b.eat() 呢?

这样就没有体现出面向对象的抽象的编程思想呀,降低了代码的可扩展性.

3.向上转型的好处?

       sleep(new Male());//调用方法时传入的参数是子类
       sleep(new Female());

         public static void sleep(Human h) //方法的参数是父类

        {

         h.sleep();

         }

如上代码就是用的向上转型,若是不用向上转型,那么有多少个子类就得在这儿写多少种不同的睡觉方法~~~~~~

说到这里是不是还是感觉云里雾里,再上个例子
Person 可以表示为一个抽象的东西就是人。比如说人可以唱歌, 就好比Person类中有一个sing方法.
那么这个抽象的类(Person 人)可以具体到两类或者更多类 比如 男人,女人 。
Man extends Person 或者 Woman extends Person
那么男人 还有 女人 分别实现sing方法。 因为男人和女人唱歌总还是有区别的嘛。

当 Person p = new Man(); p.sing(); 这个时候就是调用男人唱歌的sing方法
当 Person p = new Woman(); p.sing(); 这个时候就是调用女人的唱歌的sing方法

这样其实就是一个java的继承,多态. 利于程序扩展. 你需要理解这种设计方式,会让你写出更易维护简洁的代码。

二、向下转型

class Fruit{
	public void myName(){
		System.out.println("我是父类  水果...");
	}
}
 
class Apple extends Fruit{ 
	@Override
	public void myName() { 
		System.out.println("我是子类  苹果...");
	}
	public void myMore(){
		System.out.println("我是你的小呀小苹果~~~~~~");
	}
}
 
public class Sys{ 
	public static void main(String[] args) { 
		Fruit a=new Apple(); //向上转型
		a.myName();
		
		Apple aa=(Apple)a; //向下转型,编译和运行皆不会出错(正确的)
		aa.myName();//向下转型时调用的是子类的
		aa.myMore();;
		  
		Fruit f=new Fruit();
        Apple aaa=(Apple)f; //-不安全的---向下转型,编译无错但会运行会出错
  		aaa.myName();
  		aaa.myMore(); 
	}
}

输出:
我是子类 苹果…
我是子类 苹果…
我是你的小呀小苹果~~~~~~
Exception in thread “main” java.lang.ClassCastException: com.sheepmu.Fruit cannot be cast to com.sheepmu.Apple
at com.sheepmu.Sys.main(Sys.java:30)

由此得到向下转型的意义:父类引用可以使用子类的新增方法
详解:

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) 判断一下下

这里引出一个问题:JAVA的面向对象应该怎样理解。(之前就突然被一个面试问到对面向对象、面向过程的理解)有很多种答案,这里是B站上看到的一个老师讲的。

所有的程序其实只有三个核心元件:变量、选择语句、循环语句。
面向过程变成:我们可以通过方法,来把这三个东西放在一起。然后通过方法一方法二串联起来,最终形成一个程序。
面向对象:对象,它是一个更高级的组织方式。我们可以把方法、变量放到对象里面。更高级的组织形式可以做更复杂的程序。

本文地址:https://blog.csdn.net/ZzzplayDrea/article/details/107351329