zoukankan      html  css  js  c++  java
  • 面向对象篇之 接口&多态

    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(); //左边是一个“父类”
          }
      }
      

  • 相关阅读:
    [数据结构]线性表
    对C语言中指针的一些新认识
    Qt做动画旋转旋转图片
    延时程序执行Qt
    关于部分网页打不可的问题
    关于QString中的arg()函数使用方法
    Qt5.3.0 for Android开发环境配置
    QMenu,contextmenuevent,窗体透明
    Qt自定义窗体,边框,圆角窗体
    一个良好的团队
  • 原文地址:https://www.cnblogs.com/0x7e/p/14319998.html
Copyright © 2011-2022 走看看