1.知识点的过渡
1.1继承:
继承是建立在子类和父类的基础之上的
类之间的继承—单继承
接口之间的继承—多继承
类与接口之间的关系—一对多—实现关系:一个类实现多个接口
1.2基于以上的知识:
1.按照封装的高度来说—-接口(高)—>抽象类—>普通类
2.接口也是一个特殊的类,其实也是父类
3.如果一个子类与父类产生了关系—继承关系:从类型上来说子类属于父类的一个实例
1.3新知识:
如果说父类的引用指向子类的对象就是—-向上造型
对象的多态性,只适用于方法(编译看左边,运行看右边),不适用于属性(编译和运行都看左边)
多态的前提必须有子父类关系,或者实现接口关系
2.向上造型:是多态的一种实现
2.1向上造型
父类(接口)的引用可以指向子类的对象,展现出来的是父类(接口)的功能
- 子类的引用变量可以指向子类的对象,展现出来的是子类的功能
- 子类对象可以展现出多种形态,这多种形态叫做多态—多态后不能再调用子类特有的方法
- 格式:
- 父类类型 变量名=new 子类的对象();
- 变量名.方法名
- 当多态出现以后,编译期只能调用父类中声明的方法,但是在运行期实际执行的是子类重写父类的方法
多态的使用场景:
1.为变量赋值的时候使用多态,达到父类的引用子类的对象,直接为变量赋值
- 2.调用方法的时候,为方法的参数进行赋值
- 3.方法的返回值,可以定义为父类的类型,但是返回的是子类的对象。
- 当该方法被调用后,用父类的类型接收 ```java package duotai_01;
/**
- @author Lynn
- @create 2020-12-01-15:15 */
/**
- 父类—动物类 *
- 用于展示多态的抽象方法
吃饭,睡觉 */ public abstract class Animal { //普通方法 public void eat(){
System.out.println("吃饭");
}
//抽象方法 public abstract void sleep(); }
java package duotai_01;
/**
- @author Lynn
- @create 2020-12-01-15:17 */
/**
- 人类—子类(具体类) *
- 用于展示多态的实现
在父类的共性功能外,有自己学习,工作的方法 */ public class Person extends Animal{ @Override public void sleep() {
System.out.println("睡在床上");
}
//拓展子类自己的方法 public void study(){
System.out.println("学习使我快乐");
}
//工作的方法 public void work(){
System.out.println("工作可以创造金钱");
}
//重写父类中的方法 @Override public void eat(){
System.out.println("吃饱饭踏实");
} }
java package duotai_01;
/**
- @author Lynn
@create 2020-12-01-15:53 */ public class Dog extends Animal{ @Override public void sleep() {
System.out.println("睡在地上");
}
public void kanmen(){
System.out.println("千里无极");
}
@Override public void eat(){
System.out.println("吃骨头");
} }
java package duotai_01;
/**
- @author Lynn
- @create 2020-12-01-15:22 */
import java.security.PublicKey;
/**
- 演示向上造型 *
- 其实向上造型是多态的一种实现方式
- 父类(接口)的引用可以指向子类的对象,展现出来的是父类(接口)的功能
- 子类的引用变量可以指向子类的对象,展现出来的是子类的功能
- 子类对象可以展现出多态的实现 *
- 格式:
- 父类类型 变量名=new 子类的对象();
- 变量名.方法名 *
- 当多态出现以后,调用的方法是子类重写后的方法 *
- 多态的使用场景:
- 1.为变量赋值的时候使用多态,达到父类的引用子类的对象,直接为变量赋值
- 2.调用方法的时候,为方法的参数进行赋值
- 3.方法的返回值,可以定义为父类的类型,但是返回的是子类的对象。
当该方法被调用后,用父类的类型接收 */ public class SubClassType { public static void main(String[] args) {
//创建子类对象Person p=new Person();p.eat();p.sleep();p.work();p.study();System.out.println("-------------------------");//使用向上造型--展现出来的是父类中的功能Animal a=new Person();//调用的是父类中的方法,结果是子类中重写后的方法a.eat();//吃饱饭踏实a.sleep();//睡在床上
// a.work();//调用不到
System.out.println("-------------------------------");//调用feed方法feed(new Person());//传一个Animal的子类对象feed(new Dog());//传一个Animal的子类对象
// feed(new Animal() //Animal是一个抽象类不能被实例化
}//封装一个方法,用于灵活地调用所有的方法---传入参数是一个父类public static void feed(Animal a){//a是Animal的引用,可以接收Animal中所有的子类对象//调用该动物吃饭的方法System.out.println("feed方法内");a.eat();}
}
<a name="RpARI"></a>### 2.2重点补充:1.方法的重载和重写的区别<br />方法的重载看到的是引用;<br />方法的重写看的是对象2.方法的重载时在编译期绑定参数的--编译期就是按下保存键按钮之后jvm检查java代码的语法的时候<br />方法的重写实在运行期执行的--因为**对象实在运行期才出现的**<a name="3."></a># 3.向下造型<a name="j6qXf"></a>### 多态的实现:- 1.向上造型(向上转型):**多态本身就是子类类型向父类类型的转换** - 默认- 格式:父类类型 变量名 = new 子类对象();2.向下转型:一个已经向上转型的子类对象可以**使用强制类型转换**的格式,将父类引用转为子类引用- 格式:子类类型 变量名 = (子类类型)变量名;**注意:**<br />在强制类型转换的时候,必须是什么对象就转换为什么对象!<br />如果使用错误,使用了其他类型的对象,那么编译期不会报错,但是在运行期会报错(造型异常)<br />java.ClassCastException--表示**造型异常**```javapackage duotai_02;/*** @author Lynn* @create 2020-12-01-15:22*//*** 演示向下造型** 其实向下造型是多态的一种实现方式* 多态的实现:* 1.向上造型(向上转型):多态本身就是子类类型向父类类型的转换 - 默认* 格式:父类类型 变量名 = new 子类对象();* 2.向下转型:使用起那个值类型转换* 格式:子类类型 变量名 = (子类类型)变量名;***/public class SubClassType {public static void main(String[] args) {//创建子类对象Person p=new Person();p.eat();p.sleep();p.work();p.study();System.out.println("-------------------------");//使用向上造型--展现出来的是父类中的功能Animal a=new Person();//调用的是父类中的方法,结果是子类中重写后的方法a.eat();//吃饱饭踏实a.sleep();//吃饱饭踏实// a.work();//调用不到System.out.println("------------向下转型-----------------");Animal a1=new Dog();//向上造型/*Person p1=(Person)a1;//向下转型---强制类型转换--//造型异常(把狗造成人,不通)--对象在运行期产生的p1.eat();p1.sleep();*///正确的向下转型---注意类型Dog d1=(Dog)a1;d1.eat();//吃骨头d1.sleep();//睡在地上/*** 在强制类型转换的时候,必须是什么对象就转换为什么对象!* 如果使用错误,使用了其他类型的对象,那么编译期不会报错,但是在运行期会报错(造型异常)* java.ClassCastException--表示造型异常*//* System.out.println("-------------拓展------------------");//调用feed方法feed(new Person());//传一个Animal的子类对象feed(new Dog());//传一个Animal的子类对象// feed(new Animal() //Animal是一个抽象类不能被实例化*/}/*//封装一个方法,用于灵活地调用所有的方法---传入参数是一个父类public static void feed(Animal a){//a是Animal的引用,可以接收Animal中所有的子类对象//调用该动物吃饭的方法System.out.println("feed方法内");a.eat();}*/}
解决造型异常的方案:
使用一个instanceof关键字来判断某个对象是不是属于某种类型
最后会返回true或false,进行了对象的判断后就可以保证
使用格式:
boolean b = 对象 instanceof 数据类型;
如
Person p1 = new Student(); // 前提条件,学生类已经继承了人类
boolean flag = p1 instanceof Student; //flag结果为true
boolean flag2 = p2 instanceof Teacher; //flag结果为false
public class SubClassType {public static void main(String[] args) {System.out.println("------------向下转型-----------------");//狗Animal a1=new Dog();method(a1);//人Animal a2=new Person();method(a2);}//封装一个方法用于判断这个类型public static void method(Animal a){//如果是狗,就看门,如果是人就学习工作if(a instanceof Dog){//强制转换成狗Dog d=(Dog)a;d.kanmen();}if(a instanceof Person){//强制转换成人Person p=(Person)a;p.study();p.work();}}}
多态的好处:
- 大大提高了程序的扩展性
- 提高了程序的复用性
