Java基础知识整理【9】 (多态,里氏转化原则,抽象类和抽象方法,接口)

多态

同一个事物被不同对象所触发,得到的结果是不同的就是多态

方法多态 重载,同一个方法被不同参数所触发得到结果是不一样
对象多态必须继承,同一个事物被不同对象所触发得到的结果是不一样的

子类所有的构造方法都是调用父类的无参构造方法默认,所以父类需要提供无参构造方法否则子类的构造方法会报错

若父类没有提供无参构造方法,但是提供了其他构造方法,此时子类可以显式的调用父类的其他构造方法来完成创建

父类所提供的方法无法满足类的需求,子类可以重新实现,这个实现就是重写

有 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: 提升为父类类型的对象和原有子类类型不一致

多态中成员属性和成员方法的访问

  1. 向上转型 Father f = new Son();
    当前提升后的对象是父类类型
    System.out.println(f.num);//访问的是父类中的属性
    f.show();//访问父类中的方法
    子类有和父类中有和父类相同的属性,只会调用父类的属性

  2. 向上转型的时,1.子类没有重写父类方法,无论是向上转型还是向下转型,访问都是父类中提供方法 2.子类重写父类的方法,无论是向上转型还是向下转型,访问的都是子类重写的方法

  3. 子类中有和父类中属性名相同属性
    子类重写父类的方法
    先进行对象的向上转型,然后在执行对象的向下转型
    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();

猜你喜欢

转载自blog.csdn.net/root1994/article/details/89106626