多态
同一个事物被不同对象所触发,得到的结果是不同的就是多态
方法多态 重载,同一个方法被不同参数所触发得到结果是不一样
对象多态必须继承,同一个事物被不同对象所触发得到的结果是不一样的
子类所有的构造方法都是调用父类的无参构造方法默认,所以父类需要提供无参构造方法否则子类的构造方法会报错
若父类没有提供无参构造方法,但是提供了其他构造方法,此时子类可以显式的调用父类的其他构造方法来完成创建
父类所提供的方法无法满足类的需求,子类可以重新实现,这个实现就是重写
有 private, final, static 三者之一即可的情况下不能重写
一旦重写只有在子类中使用super.方法名的方式才能调出父类的方法
其与方式一律执行子类重写方法
@Override // --> 注解(标签)提示编译器加载子类的时候先检查是否有已经重写父类的方法
public void showMoney() {
System.out.println("薪水是:"+(getMoney()+jiangjin));
}
@Override
public String toString() {
return "姓名:"+name+" "+"底薪:"+getMoney()+" "+"奖金:"+jiangjin;
}
多态在Java中体现为两种:
1.方法的重载: 在一个类中允许存在相同方法名的方法,但是方法中的参数不同的,完成的方法也不同
ps:同一个方法被不用参数所触发的到的结果是不同的—> 方法(重载)多态 方法(重载)多态不需要继承
2.对象多态: 必须是继承关系,子类和父类之间可以互相转换,而且根据其使用的子类不同,得到结果也不一样
ps:同一个事物被不同对象所触发得到的结果不同.—> 对象多态 必须是继承关系
多态的作用: 当把不用子类的对象都当做父类看待时,可以屏蔽掉不同子类之间的实现差异,从而写出通用的代码 多态的好处:
1.提高代码的维护性(继承保证)
2.提高代码的可扩展性(多态保证)
用多态的概念,作为方法的参数 父类可以接受一个子类的引用
多态的弊端:
一旦提升为父类类型,就不可以调用子类的特有属性和行为
里氏代转换原则
对象的向上转型
语法:父类类型 引用(对象名) = new 子类构造方法();
对象的向下转型
将已经提升为父类类型的引用(对象),强制转换为原有子类类型的过程 此时当前引用(对象)
语法: 原有子类类型 引用(对象名) = (原有子类类型)已经提升为父类的类型;
instanceof是为了防止向上转型的时候出现异常情况,增加代码的稳定性
if(a2 instanceof Dog) { // 对象向下转型
Dog dog2 = (Dog)a2;
}else {
System.out.println("a2不是Dog类型无法转换");
}
instanceof 关键字
语法: 提升为父类类型的对象 instanceof 原有子类类型
结果: boolean类型的返回值
true:提升为父类类型的对象和原有子类类型一致
false: 提升为父类类型的对象和原有子类类型不一致
多态中成员属性和成员方法的访问
-
向上转型 Father f = new Son();
当前提升后的对象是父类类型
System.out.println(f.num);//访问的是父类中的属性
f.show();//访问父类中的方法
子类有和父类中有和父类相同的属性,只会调用父类的属性 -
向上转型的时,1.子类没有重写父类方法,无论是向上转型还是向下转型,访问都是父类中提供方法 2.子类重写父类的方法,无论是向上转型还是向下转型,访问的都是子类重写的方法
-
子类中有和父类中属性名相同属性
子类重写父类的方法
先进行对象的向上转型,然后在执行对象的向下转型
Father f = new Son(); //对象的向上转型,此时是父类类型
Son s = (Son)f; //对象的向下转型,此时会转换为原有子类类型
当前对象是子类类型,访问的就是子类中属性
System.out.println(s.num);
s.show();//show一定是子类重写方法
抽象类和抽象方法
抽象类就是一个特殊父类
父类是不会直接创建对象(父类类型 对象名 = new 父类类型()),只是给子类提供方法和属性
开发中,父类不会直接创建对象,只会给子类提供方法和属性,java提供关键字abstract 抽象的,这个关键字可以保证父类提供的方法和属性被子类所继承,而且防止这个抽象类被误创建
abstract关键字不能和final关键字共存
抽象类定义:
访问权限修饰符 abstract class 类名{ 如何定义父类就如何定义抽象类即可
}
抽象方法:访问权限修饰符 abstract 返回值类型 方法名(参数列表);
只要普通子类继承了抽象类必须实现抽象类中的抽象方法,不然类会报错,抽象方法没有方法体,并且因为方法必然会被子类重写 所以全新修饰符 不能使用 private 也不能使用 static
抽象方法
- 1.抽象方法一定没有方法体
- 2.抽象方法需要使用abstract关键字修饰
- 3.若抽象方法存在在类中,那么这个类必须是抽象类
抽象类
- 1.抽象方法若存在在一个类中,这个类必须是抽象类
- 2.抽象类中可以不提供抽象方法 public abstract void show();没有方法体
- 3.一个普通类若继承于一个抽象类,那么必须实现抽象类抽象方法
- 4.一个抽象类继承于另外一个抽象类,当前抽象子类可以实现抽象父类中抽象方法 也可以不实现,抽象子类可以添加自己抽象方法
- 5.一个普通类继承一个抽象子类,需要实现所有没有实现的抽象方法
- 6.抽象类是不能直接创建对象
接口
当做是一个特殊的抽象父类
JDK1.7 之前包含1.7都只能定义全局静态常量和抽象方法;1.8之后加了两个有实现体的方法 default方法和static方法
代码举例:
public interface ISunflowerBible {
//全局静态常量 -->常量名全大写
//默认修饰 public static final //数据类型 常量名 = 值;
String BOOK_NAME = "葵花宝典";
//抽象方法
//默认修饰 public abstract
// 返回值类型 方法名(参数列表);
void liangong();
//default方法 --> 看做是类中成员方法
//public default 返回值类型 方法名(参数列表){ 方法体}
default void showInfosDefault() {//默认修饰
public System.out.println("接口中的default方法");
}
//static方法 --> 看做是类中的静态方法
//public static 返回值类型 方法名(参数列表){ 方法体;}
static void showInfosStatic() {//默认修饰
public System.out.println("接口中static方法");
}
}
调用时:接口名.常量名
- static修饰的方法不能被重写
- default方法可以被重写
- 实现接口的类只实现了抽象方法没有重写default,外部如何调用
接口中default方法可以使用接口实现类调用
new JDK1_8Demo().showInfosDefault();
//静态方法调用,通过接口名.静态方法名调用
InterfaceForJDK1_8.showInfosStatic();