• 抽象类与接口


    一、抽象类

    1.1.抽象类的概述:

    ​ 我们把一个不是具体的功能称为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类。

    • 抽象类的特点:
    • 抽象类和抽象方法必须用abstract关键字修饰
    • 抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类 (即带有抽象方法的)
    • 抽象类不能实例化
      因为它不是具体的。
      抽象类有构造方法,但是不能实例化,构造方法的作用是 用于子类访问父类数据的初始化
    • 抽象的子类
      a:被抽象类abstract修饰的子类,也是一个抽象类
      b:不加abstract的话,通过多态,抽象类的子类可以被实例化,但是必须重写抽象类中所有的抽象方法.
      抽象类的实例化其实是靠具体的子类实现的。是多态的方式。
      Animal a = new Cat();(前提是cat已经被实例化)

    1.2.抽象类的成员特点

    • 成员变量:抽象类的成员方法既可以是常量,也可以是变量,但是不可以抽象化
    • 构造方法:抽象类有成员方法,用于子类访问父类数据的初始化
    • 成员方法:既可以是抽象的也可以是非抽象的
      抽象类成员方法的特性:
      1.抽象方法:强制要求子类必须做的事,即子类必须重写父类有的抽象方法
      2.非抽象方法:子类可以从父类继承的,提高代码复用性

    示例代码:

    //这是一个抽象类
    abstract class Animel{
        public abstract void eat();//正确,不带主体的抽象方法
        //public abstract void sleep() {}//报错,因为抽象方法不能有主体。即大括号中的代码块
        public void sleep(){
            System.out.println("睡觉");//这是抽象类中的一个非抽象方法,可以被子类继承的
        }
    }
    abstract class dog extends Animel{}//如果加了abstract,抽象类的子类也是抽象类
    
    class cat extends Animel{
        public void eat() {
            System.out.println("吃饭");
            //不加abstract的话,通过多态,抽象类的子类可以被实例化,但是必须重写抽象类中所有的的方法
            //如果没有全部重写,将会报错
        }
    }
    
    public class AbstractTest {
    
        public static void main(String[] args) {
    
            //Animel a = new Animel();//错误,抽象类不能直接实例化
            Animel a= new cat();//抽象类通过多态实现子类实例化
            a.eat();
            a.sleep();//未被抽象的方法
            cat c= new cat();//具体对象调用
            c.eat();
            c.sleep();
        }
    

    运行结果:

    吃饭
    睡觉
    吃饭
    睡觉
    

    1.3.抽象类的注意事项

    抽象类的使用限制

    1. 不能与final (冲突)
    2. private(冲突)
    3. static(无意义) 共存
      原因:首先因为被final和private修饰的方法不允许被重写或者覆盖,而被abstract修饰的方法又必须在子类中重写,所以这abstract与这两个关键字冲突,关于static关键字,因为被abstract修饰的方法不允许有方法体,而被static修饰的方法可以直接通过类名调用,而调用一个没有方法体的方法是没有意义的

    1.4.抽象类总结

    1、抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。
    2、抽象方法必须由子类来进行重写。
    3、只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含有其他方法。
    4、抽象类中可以包含具体的方法,当然也可以不包含抽象方法。
    5、子类中的抽象方法不能与父类的抽象方法同名。
    6、abstract不能与final并列修饰同一个类。
    7、abstract 不能与private、static、final或native并列修饰同一个方法。、

    1.5.抽象类的三种调用方式

    abstract class Animel{
        private int age ;
        private String name;
        abstract void eat() ;
        Animel(){};
        public Animel(String name,int age) {
            this.name=name;
            this.age=age;
        }
        public void SetName(String name) {
            this.name =name;
        }
        public void SetAge(int age) {
            this.age=age;
        }
        public String GetName() {
            return name;
        }
        public int GetAge() {
            return age;
        }
    }
    class dog extends Animel{
        public dog() {};
        public dog(String name,int age) {
            super(name,age);
        }
        public void eat() {
            System.out.println("狗吃肉");
        }
    
    }
    public class CatDemo {
        public static void main(String[] args) {
            //调用方式一,构造方法调用
            dog d = new dog("哈士奇",20);
            d.eat();
            System.out.println(d.GetAge()+"------"+d.GetName());
            System.out.println("------------");
            //   调用方式二,具体调用
            dog d1= new dog();
            d1.eat();
            d1.SetAge(19);
            d1.SetName("哈巴狗");
            System.out.println(d1.GetAge()+"------"+d1.GetName());
            System.out.println("------------");
            //调用方式三.抽象调用
            Animel d2 = new dog();
            d2.eat();
            d2.SetAge(99);
            d2.SetName("萌犬");
            System.out.println(d2.GetAge()+"------"+d2.GetName());
        }
    }
    

    二、接口

    2.1.接口的概述

    • 接口用关键字interface表示 (注意,接口不需要加class)
      interface 接口名 {}

    • 类实现接口用implements
      class 类名 implements 接口名 {}

    • 接口不能直接实例化 ,如果需要实例化,必须按照多态的方式来实例化,即利用一个非抽象化的子类进行实例化

    • 接口的子类 ,可以是抽象类。但是意义不大。也可以是具体类。但是必须要重写接口中的所有抽象方法。

    • 接口并不是实际的一个类,而是功能的拓展,由此可见多态有三种实现方法:

      ​ A:具体类多态(很少用)
      ​ B:抽象类多态(常用)
      ​ C:接口多态(最常用)

      ps(1.接口名+Impl这种格式是接口的实现类惯用格式 ,2,在实现接口的时候需要注意调用的时候只能调用该接口有的方法 )

    2.2.接口的成员特点

    • 成员变量:接口中的变量默认是常量,默认带有 public static final ,不可被重新赋值,同时因为它是静态的, 因此即使另一个类处于不同包下,也可以通过接口名.成员变量名来访问接口里的成员变量。,但是建议自己手动给出public static final,
    • 成员方法:接口中的方法只能是抽象方法,且默认为抽象方法,即使没有加抽象修饰符abstract,
      因为接口中的成员方法默认加了public abstract,但是为了直观,依旧建议自己手动给出public abstract ,而且, 接口中的成员方法与抽象类类似,都不带有方法主体
    • 构造方法:接口没有构造方法

    2.3.接口与类之间的关系

    • 与类:
      继承关系,只能单继承,可以多层继承。(不允许存在son extends father, mother{}这种情况 )
    • 类与接口:
      实现关系,可以单实现,也可以多实现。(例如:class Son implements Father,Mother{})
      并且还可以在继承一个类的同时实现多个接口。(class son extends father implements mother,sister {}(解释:子类继承父类并实现母和姐妹接口))
    • 接口与接口:
      继承关系,可以单继承,也可以多继承。(interface Sister extends Father,Mother { })继承的接口,可以继承功能

    三、抽象类与接口的区别

    3.1.成员区别

    • ​ 抽象类:
      ​ 成员变量:可以变量,也可以常量
      ​ 构造方法:有 构造方法
      ​ 成员方法:可以抽象,也可以非抽象
    • 接口:
      成员变量:只可以常量 (即被static final)
      成员方法:只有抽象 方法
      没有构造方法

    3.2.关系区别

    • 类与类 继承,单继承
    • 类与接口 实现,单实现,多实现
    • 接口与接口 继承,单继承,多继承

    3.3.设计理念区别

    ​ 抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能,大致来说当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口,通俗的说,类用来抽象共性,而接口用于抽象功能,例如鸟和猫可以抽取一个动物的共性,但是鸟和飞机一般是抽象出一个fly()的行为的接口。

  • 相关阅读:
    HIVE中内连接和左半连接不一致问题
    hive 中的Sort By、 Order By、Cluster By、Distribute By 区别
    基于MapReduce的矩阵乘法运算
    基于MapReduce的关系代数运算(2)
    基于MapReduce的关系代数运算(1)
    帖子爬取
    tomcat------https单向认证和双向认证
    struts2配置文件struts.xml的简介
    2014,事情只有一件!
    MYSQLi数据访问查询数据
  • 原文地址:https://www.cnblogs.com/blackmlik/p/12076972.html
Copyright © 2020-2023  润新知