1  抽象类

 

通常可以说四边形具有4条边,或者更具体一点,平行四边形是具有对边平行且相等特性的特殊四边形,等腰三角形是其中两条边相等的三角形,这些描述都是合乎情理的,但对于图形对象却不能使用具体的语言进行描述,它有几条边,究竟是什么图形,没有人能说清楚,这种类在Java中被定义为抽象类。

在解决实际问题时,一般将父类定义为抽象类,需要使用这个父类进行继承与多态处理。在多态机制中,并不需要将父类初始化对象,我们需要的只是子类对象,所以在Java语言中设置抽象类不可以实例化对象,因为图形类不能抽象出任何一种具体图形,但它的子类却可以。

抽象类的语法如下∶

public abstract class Test{ abstract vold testAbstract);  }   //定义抽象方法

其中,abstract 是定义抽象类的关键字。 使用 abstract关键字定义的类称为抽象类,而使用这个关键字定义的方法称为抽象方法。抽象方法没有方法体,这个方法本身没有任何意义,除非它被重写,而承载这个抽象方法的抽象类必须被继承,实际上抽象类除了被继承之外没有任何意义。

只要类中有一个抽象方法,此类就被标记为抽象类。

抽象类被继承后需要实现其中所有的抽象方法,也就是保证相同的方法名称、参数列表和相同返回值类型创建出非抽象方法,当然也可以是抽象方法。


java工具 四边形判断经纬度 java判断四边形类型_子类

抽象类继承关系

public abstract class Animal {
    String name;

    public Animal(String name) {
        this.name = name;
    }
    public Animal(){}

    /*
        抽象方法
        不能拥有方法体
         */
    public abstract void run();

    public void show(){
        System.out.println("Animal show()");
    }

}
public abstract class Dog extends Animal {

    public abstract void lookHome();

    
}
public class SmallDog extends Dog {
    @Override
    public void lookHome() {

        System.out.println("lookHome");
    }

    @Override
    public void run() {
        System.out.println("run......");
    }

    @Override
    public void show() {
        System.out.println("smallDog show()");
    }
}

总结:

1.当一个类继承了一个抽象类 则必须【实现】抽象类中的抽象方法 或者 将 实现类也变为抽象类
2.抽象类中可以存在普通的属性 也可以存在普通的方法
3.抽象类中可以没有抽象方法
4.抽象方法只能存在抽象类内
5.子类需要实现所有的抽象方法 不仅是父亲的 爷爷的也要实现
6.抽象类不能创建对象 需要借助子类实现功能

 

2. 接口

接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体。接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能跑。接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。

2.1 接口

声明格式:

[访问修饰符]  interface 接口名   [extends  父接口1,父接口2…]  {

常量定义;

方法定义;

}


 定义接口的详细说明:

  1. 访问修饰符:只能是public或默认。
  2. 接口名:和类名采用相同命名机制。
  3. extends:接口可以多继承。
  4. 常量:接口中的属性只能是常量,总是:public static final 修饰。不写也是。
  5. 方法:接口中的方法只能是:public abstract。 省略的话,也是public abstract。

要点

  1. 子类通过implements来实现接口中的规范。
  2. 接口不能创建实例,但是可用于声明引用变量类型。
  3. 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的。
  4. JDK1.8(不含8)之前,接口中只能包含静态常量、抽象方法,不能有普通属性、构造方法、普通方法。
  5. JDK1.8含8后,接口中包含普通的静态方法默认方法。

 

 

*实例:

需求:飞机、鸟、超人,导弹参加飞行表演
思路1:定义一个父类Flyable,让飞机、鸟、超人,导弹都继承该类。不可以,因为继承表达的是is-a的关系,而飞机、鸟、超人不是一种事物,
思路2:使用接口,定义一个接口Flyable,让飞机、鸟、超人,导弹都实现该接口。接口表达是has-a的关系

接口: 定义了一种规范  表示 has a的关系
    1.如何声明接口 权限修饰符 interface 接口名
    2.接口中的方法是抽象方法 ?
    3.一个类实现了接口 则 必须实现 接口内的方法 否则 此类 要变为 抽象类
    4.当一个类实现了接口 则 此类可以作为此接口的子类存在
    5.一个类可以实现多个接口 必须实现各个接口中的方法 否则 此类变为抽象类
    6.一个接口可以继承多个接口  实现此接口的额类 需要 实现各个接口内的方法  否则 将此类变为抽象类
    7.接口中的变量 是全局静态 常量
      默认被 public staic final 修饰
    8.接口内的方法 默认被 public abstract 修饰

/*接口: 定义了一种规范  表示 has a的关系
    1.如何声明接口 权限修饰符 interface 接口名
    2.接口中的方法是抽象方法 ?
    3.一个类实现了接口 则 必须实现 接口内的方法 否则 此类 要变为 抽象类
    4.当一个类实现了接口 则 此类可以作为此接口的子类存在
    5.一个类可以实现多个接口 必须实现各个接口中的方法 否则 此类变为抽象类
    6.一个接口可以继承多个接口  实现此接口的额类 需要 实现各个接口内的方法  否则 将此类变为抽象类
    7.接口中的变量 是全局静态 常量
      默认被 public staic final 修饰
    8.接口内的方法 默认被 public abstract 修饰*/

public interface Fly {
    public final   static String NAME = "FLY";
    void fly();   //public abstract
}
public interface SaveWord {

    public void savaWorld();
}

public class Daodan implements Fly {
    @Override
    public void fly() {
        System.out.println("导弹 会飞 ");
    }
}

public abstract class FeiJi implements TwoInOne {

}

public class SuperMan implements Fly,SaveWord {
    @Override
    public void fly() {
        System.out.println("超人会飞");
    }

    @Override
    public void savaWorld() {
        System.out.println("拯救世界");
    }
}

public class Test {
    public static void main(String[] args) {
        Fly daodan = new Daodan();//多态
        daodan.fly();
        SuperMan superMan = new SuperMan();
        SaveWord sp = new SuperMan();
        sp.savaWorld();
        superMan.fly();
        System.out.println(superMan.NAME);

    }
}

2.2  接口新特征

JDK7及其之前

  1. 接口的变量都是public final static 全局静态常量,无变化
  2. 接口中都是抽象abstract方法,不能有static方法(因为abstract和static、final、private不能共存)

JDK8及其之后

  1. 接口中可以添加非抽象方法(static),实现类不能重写,只能通过接口名调用。
  2. 如果子类中定义了相同名字的静态方法,那就是完全不同的方法了,直接从属于子类。可以通过子类名直接调用
  3. 接口中可以添加非抽象方法(default),实现类可以重写,只能通过对象名调用
  4. 实现类可以直接使用default方法,可以重写default方法,但是必须去掉default。(default只能接口中使用)
  5. 上级接口中default方法的调用:MyInterface.super.method2()

提供非抽象方法的目的

  1. 为了解决实现该接口的子类代码重复的问题
  2. 为了既有的成千上万的Java类库的类增加新功能,且不必对这些类重新进行设计。比如只需在Collection接口中增加default Stream<E> stream(),相应的Set和List接口以及它们的子类都包含此的方法,不必为每个子类都重新copy这个方法。

JDK9及其之后

接口中可以定义private的非抽象方法,便于将多个方法中的冗余代码进行提取,并且不对外公开。减少冗余、也实现了代码隐藏。

 

2.3 面向接口编程

面向接口编程是面向对象编程的一部分。

为什么需要面向接口编程? 软件设计中最难处理的就是需求的复杂变化,需求的变化更多的体现在具体实现上。我们的编程如果围绕具体实现来展开就会陷入”复杂变化”的汪洋大海中,软件也就不能最终实现。我们必须围绕某种稳定的东西开展,才能以静制动,实现规范的高质量的项目。

接口就是规范,就是项目中最稳定的核心! 面向接口编程可以让我们把握住真正核心的东西,使实现复杂多变的需求成为可能。

通过面向接口编程,而不是面向实现类编程,可以大大降低程序模块间的耦合性,提高整个系统的可扩展性和和可维护性。

面向接口编程的概念比接口本身的概念要大得多。设计阶段相对比较困难,在你没有写实现时就要想好接口,接口一变就乱套了,所以设计要比实现难!