面向对象篇之 接口&多态

0x01、接口

在前面写的几篇文章里,讲了封装和继承,那么这篇文章就来讲讲第三大面向对象的特性多态吧,在此之前先接着上篇文章的抽象先来看看Java里面接口的应用。

(1)、定义格式

public interface IA {
    // 常量 默认修饰符是 public static final 这3个修饰符可以省略不写
    int NUM = 10;

    // 抽象方法 默认修饰符是 public abstract 这2个修饰符可以省略不写
    void method1();

    // 默认方法 默认修饰符是 public
    default void method3(){
        System.out.println("IA 接口默认方法");
    }

    // 静态方法 默认修饰符 public
    static void method4(){
        System.out.println("静态方法");
    }

    // 私有方法 修饰符 private   private不可以省略
    private void method5(){
        System.out.println("私有非静态方法");
    }

    private static void method6(){
        System.out.println("私有静态方法");
    }
}

(2)、实现接口

实现概述

类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements关键字。

public interface IA{
    public void show1();
}
public interface IB{
    public void show2();
}
public class Zi implements IA ,IB{
    public void show1(){
    }
    public void show2(){
    }
}
  • 类可以实现一个接口,也可以同时实现多个接口。

  • 类实现接口后,必须重写接口中所有的抽象方法,否则该类必须是一个“抽象类”。

    public interface IA{ public void show1();}
    
    public interface IB{ public void show2();}
    
    public class Zi implements IA ,IB{
        public void show1(){
        }
        public void show2(){
        }
    }
    
  • 类可以在“继承一个类”的同时,实现一个、多个接口

public class Fu{}
public interface IA{}
public interface IB{}
public class Zi extends Fu implements IA,IB{//一定要先继承,后实现
}

(3)、 接口中成员的访问特点:

接口中的常量: 主要是供接口直接使用
接口中的抽象方法: 供实现类重写的
接口中的默认方法: 供实现类继承的(实现类中可以直接调用,实现类对象也可以直接调用)

接口中的静态方法: 只供接口直接调用,实现类继承不了
接口中的私有方法: 只能在接口中直接调用,实现类继承不了

(4)、多实现时的几种冲突

公有静态常量的冲突
  • 实现类不继承冲突的变量
interface IA{
    public static final int a = 10;
    public static final int b= 20;
}
interface IB{
    public static final int a = 30;
}
class Zi implements IA,IB{
    //只继承了b,没有继承a,因为a冲突了
}

public class Demo {
    public static void main(String[] args) {
        Zi z = new Zi();
     //   System.out.println(z.a);//编译错误
        System.out.println(z.b);
    }
}

公有抽象方法的冲突
  • 实现类只需要重写一个
公有默认方法的冲突
  • 实现类必须重写一次最终版本
公有静态方法的冲突
  • 静态方法是直接属于接口的,不能被继承,所以不存在冲突
私有方法的冲突
  • 私有方法只能在本接口中直接使用,不存在冲突

(5)、实现类继承父类又实现接口的冲突

父类和接口的公有静态常量的冲突

  • 无法继承两个重名的变量

父类和接口的抽象方法冲突

  • 重写方法

父类和接口的公有默认方法的冲突

  • 继承父类的默认方法,不继承接口

父类和接口的公有静态方法

  • 只继承了"父类"的静态方法,没有继承接口的静态方法
父类和接口的私有方法
  • 不存在冲突

0x02、多态

多态是继封装、继承之后,面向对象的第三大特性。

  • 多态: 是指同一行为,对于不同的对象具有多个不同表现形式。
  • 程序中多态: 是指同一方法,对于不同的对象具有不同的实现.

(1)、前提条件【重点】

  1. 继承或者实现【二选一】

  2. 父类引用指向子类对象【格式体现】

    Fu fu = new Zi();
    
  3. 方法的重写【意义体现:不重写,无意义】

(2)、实现多态

多态的体现:父类的引用指向它的子类的对象

父类类型 变量名 = new 子类对象;
变量名.方法名();

父类类型:指子类对象继承的父类类型,或者实现的父接口类型。

class Animal{}
class Cat extends Animal{}
class Dog extends Animal{}
clsss Person{}
//测试类:
main(){
    Animal a1 = new Cat();
    Animal a2 = new Dog();
    Animal a3 = new Person();//编译错误,没有继承关系。
}

注意:多态的情况下是无法访问子类独有的方法

Animal父类代码:

public class Animal {

    int num = 10;

    public void eat(){
        System.out.println("吃东西...");
    }

    public static void sleep(){
        System.out.println("Animal类中的睡觉方法...");
    }

}

Dog 继承Animal父类:

public class Dog extends Animal {

    int num = 20;

   // 重写
    public void eat() {
        System.out.println("狗吃骨头");
    }

    public static void sleep(){
        System.out.println("Dog类中的睡觉方法...");
    }

    public void lookHome(){
        System.out.println("狗正在看家...");
    }

}

mian方法

public class Demo1 {
    public static void main(String[] args) {
        
        // 父类的引用指向子类的对象
        Animal anl1 = new Dog();
        // 访问非静态方法
        anl1.eat();

        // 访问成员变量num
        System.out.println(anl1.num);//10

        // 访问静态方法
        anl1.sleep();

        // 多态想要调用子类中独有的方法
        // anl1.lookHome(); 错误的,无法访问  多态的弊端:无法访问子类独有的方法

    }
}

(3) 引用类型转换

向上转型
  • 子类类型向父类类型 向上转换的过程,这个过程是默认的。(只能调用父类,不能调用子类独有)

     Aniaml anl = new Cat();  
    
向下转型
  • 父类类型向子类类型向下转换的过程,这个过程是强制的。

     Aniaml anl = new Cat();  
     Cat c = (Cat)anl;//向下转型
     c.catchMouse();// 可以访问 子类独有的功能,解决多态的弊端
    
    
instanceof关键字
  • 向下强转有风险,最好在转换前做一个验证 :

  • 格式:

    变量名 instanceof 数据类型 
    如果变量属于该数据类型,返回true。
    如果变量不属于该数据类型,返回false。
    
    if( anl instanceof Cat){//判断anl是否能转换为Cat类型,如果可以返回:true,否则返回:false
        Cat c = (Cat)anl;//安全转换
    }
    

(4)、多态的几种表现形式

  • 多态的表现形式:

    • 普通父类多态

      public class Fu{}
      public class Zi extends Fu{}
      public class Demo{
          public static void main(String[] args){
              Fu f = new Zi();//左边是一个“父类”
          }
      }
      
      
    • 抽象父类多态

      public abstract class Fu{}
      public class Zi extends Fu{}
      public class Demo{
          public static void main(String[] args){
              Fu f = new Zi();//左边是一个“父类”
          }
      }
      
      
    • 父接口多态

    public interface A{}
    public class AImp implements A{}
    
    public class Demo{
        public static void main(String[] args){
            A a = new AImp(); //左边是一个“父类”
        }
    }
    

posted @ 2021-01-24 08:09  0X7e  阅读(142)  评论(0编辑  收藏  举报