Java语言基础学习关键字:abstract和interface

一、抽象类与抽象方法

1.抽象类定义:

随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。

2.abstract关键字的使用

不能用abstract修饰变量、代码块、构造器;

不能用abstract修饰私有方法、静态方法、final的方法、final的类。

abstract修饰类:抽象类

此类不能实例化。

 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)。

 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作。

含有抽象方法的类必须被声明为抽象类。

abstract修饰方法:抽象方法

抽象方法只有方法的声明,没有方法体,以分号结束。比如:public abstract void talk();

包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。

若子类重写了父类中的所有的抽象方法后,此子类方可实例化

若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰。

public class AbstractTest {

  public static void main(String[] args) {


    //一旦Person类抽象了,就不可实例化

// Person p1 = new Person();

// p1.eat();


  }

}

abstract class Creature{

  public abstract void breath();

}

abstract class Person extends Creature{

  String name;

  int age;


  public Person(){


  }

  public Person(String name,int age){

    this.name = name;

    this.age = age;

  }


  //不是抽象方法:

// public void eat(){

//

// }

  //抽象方法

  public abstract void eat();


  public void walk(){

    System.out.println("人走路");

  }



}

class Student extends Person{


  public Student(String name,int age){

    super(name,age);

  }

  public Student(){

  }


  public void eat(){

    System.out.println("学生多吃有营养的食物");

  }

  @Override

  public void breath() {

    System.out.println("学生应该呼吸新鲜的没有雾霾的空气");

  }

}

3.创建抽象类的匿名子类对象。

public class PersonTest {


  public static void main(String[] args) {


    method(new Student());//匿名对象


    Worker worker = new Worker();

    method1(worker);//非匿名的类非匿名的对象


    method1(new Worker());//非匿名的类匿名的对象


    System.out.println("********************");


    //创建了一匿名子类的对象:p

    Person p = new Person(){

      @Override

      public void eat() {

        System.out.println("吃东西");

      }

      @Override

      public void breath() {

        System.out.println("好好呼吸");

      }


    };


    method1(p);

    System.out.println("********************");

    //创建匿名子类的匿名对象

    method1(new Person(){

      @Override

      public void eat() {

        System.out.println("吃好吃东西");

      }

      @Override

      public void breath() {

        System.out.println("好好呼吸新鲜空气");

      }

    });

  }



  public static void method1(Person p){

    p.eat();

    p.breath();

  }


  public static void method(Student s){


  }

}

class Worker extends Person{

  @Override

  public void eat() {

  }

  @Override

  public void breath() {

  }


}

学习视频https://www.youtube.com/watch?v=nxd54QjNDfo&list=PLmOn9nNkQxJH0qBIrtV6otI0Ep4o2q67A&index=345

4.抽象类的应用:模板方法设计模式(TemplateMethod)

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模 板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象 类的行为方式。

解决的问题:

当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以 把不确定的部分暴露出去,让子类去实现。

换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用, 这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽 象出来,供不同子类实现。这就是一种模板模式。

public class TemplateTest {

  public static void main(String[] args) {


    SubTemplate t = new SubTemplate();


    t.spendTime();

  }

}

abstract class Template{


  //计算某段代码执行所需要花费的时间

  public void spendTime(){


    long start = System.currentTimeMillis();


    this.code();//不确定的部分、易变的部分


    long end = System.currentTimeMillis();


    System.out.println("花费的时间为:" + (end - start));


  }


  public abstract void code();



}

class SubTemplate extends Template{

  @Override

  public void code() {


    for(int i = 2;i <= 1000;i++){

      boolean isFlag = true;

      for(int j = 2;j <= Math.sqrt(i);j++){


        if(i % j == 0){

          isFlag = false;

          break;

        }

      }

      if(isFlag){

        System.out.println(i);

      }

    }

  }


}

public class TemplateMethodTest {

  public static void main(String[] args) {

    BankTemplateMethod btm = new DrawMoney();

    btm.process();

    BankTemplateMethod btm2 = new ManageMoney();

    btm2.process();

  }

}

abstract class BankTemplateMethod {

  // 具体方法

  public void takeNumber() {

    System.out.println("取号排队");

  }

  public abstract void transact(); // 办理具体的业务 //钩子方法

  public void evaluate() {

    System.out.println("反馈评分");

  }

  // 模板方法,把基本操作组合到一起,子类一般不能重写

  public final void process() {

    this.takeNumber();

    this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码

    this.evaluate();

  }

}

class DrawMoney extends BankTemplateMethod {

  public void transact() {

    System.out.println("我要取款!!!");

  }

}

class ManageMoney extends BankTemplateMethod {

  public void transact() {

    System.out.println("我要理财!我这里有2000万美元!!");

  }

}

二、接口

1.接口的概述

Java中,接口和类是并列的两个结构。

一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方 法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。

另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又 没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打 印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都 支持USB连接。

接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要...则 必须能...”的思想。继承是一个"是不是"的关系,而接口实现则是 "能不能" 的关系。

接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都 要遵守。

2.接口的定义与特点

2.1如何定义接口:定义接口中的成员

JDK7及以前:接口中只能定义全局常量和抽象方法

>全局常量:public static final修饰但是书写时,可以省略不写。

>抽象方法:public abstract修饰

 接口的主要用途就是被实现类实现。(面向接口编程)

JDK8:接口中除了定义全局常量和抽象方法之外,还可以定义静态方法( static 关键字修饰)、默认方法( default 关键字修饰)。

public interface CompareA {


  //静态方法

  public static void method1(){

    System.out.println("CompareA:北京");

  }

  //默认方法

  public default void method2(){

    System.out.println("CompareA:上海");

  }

  //默认方法

  default void method3(){//省略了public

    System.out.println("CompareA:上海");

  }

}

2.2接口的特点:

用interface来定义, 接口(interface)是抽象方法和常量值定义的集合。

接口中的所有成员变量都默认是由public static final修饰的。

接口中的所有抽象方法都默认是由public abstract修饰的。

接口中没有构造器。意味着接口不可以实例化。

接口采用多继承机制。接口与实现类之间存在多态性(接口不能实例化)。

Java开发中,接口通过让类去实现(implements)的方式来使用.

>如果实现类覆盖了(重写)接口中的所有抽象方法,则此实现类就可以实例化。

>如果实现类没有覆盖(没有重写)接口中所有的抽象方法,则此实现类仍为一个抽象类。

一个Java类可以实现多个接口 --->弥补了Java单继承性的局限性。

* 格式:class AA extends BB implements CC,DD,EE

接口与接口之间可以继承,而且可以多继承。

public class InterfaceTest {

  public static void main(String[] args) {

    System.out.println(Flyable.MAX_SPEED);

    System.out.println(Flyable.MIN_SPEED);

// Flyable.MIN_SPEED = 2;


    Plane plane = new Plane();

    plane.fly();

  }

}

interface Flyable{


  //全局常量

  public static final int MAX_SPEED = 7900;//第一宇宙速度

  int MIN_SPEED = 1;//省略了public static final


  //抽象方法

  public abstract void fly();

  //省略了public abstract

  void stop();



  //Interfaces cannot have constructors

// public Flyable(){

//

// }

}

interface Attackable{


  void attack();


}//类与接口的关系:实现关系

class Plane implements Flyable{

  @Override

  public void fly() {

    System.out.println("通过引擎起飞");

  }

  @Override

  public void stop() {

    System.out.println("驾驶员减速停止");

  }


}

abstract class Kite implements Flyable{

  @Override

  public void fly() {


  }


}

class Bullet extends Object implements Flyable,Attackable,CC{

  @Override

  public void attack() {

    // TODO Auto-generated method stub


  }

  @Override

  public void fly() {

    // TODO Auto-generated method stub


  }

  @Override

  public void stop() {

    // TODO Auto-generated method stub


  }

  @Override

  public void method1() {

    // TODO Auto-generated method stub


  }

  @Override

  public void method2() {

    // TODO Auto-generated method stub


  }


}

//**************接口与接口继承**********************

interface AA{

  void method1();

}

interface BB{


  void method2();

}

interface CC extends AA,BB{


}

 3.接口的使用

接口使用上也满足多态性

接口,实际上就是定义了一种规范

开发中,体会面向接口编程!

public class USBTest {

  public static void main(String[] args) {


    Computer com = new Computer();

    //1.创建了接口的非匿名实现类的非匿名对象

    Flash flash = new Flash();

    com.transferData(flash);


    //2. 创建了接口的非匿名实现类的匿名对象

    com.transferData(new Printer());


    //3. 创建了接口的匿名实现类的非匿名对象

    USB phone = new USB(){

      @Override

      public void start() {

        System.out.println("手机开始工作");

      }

      @Override

      public void stop() {

        System.out.println("手机结束工作");

      }


    };

    com.transferData(phone);



    //4. 创建了接口的匿名实现类的匿名对象


    com.transferData(new USB(){

      @Override

      public void start() {

        System.out.println("mp3开始工作");

      }

      @Override

      public void stop() {

        System.out.println("mp3结束工作");

      }

    });

  }

}

class Computer{


  public void transferData(USB usb){//USB usb = new Flash();

    usb.start();


    System.out.println("具体传输数据的细节");


    usb.stop();

  }



}

interface USB{//定义了一种规范

  //常量:定义了长、宽、最大最小的传输速度等


  void start();


  void stop();


}

class Flash implements USB{

  @Override

  public void start() {

    System.out.println("U盘开启工作");

  }

  @Override

  public void stop() {

    System.out.println("U盘结束工作");

  }


}

class Printer implements USB{

  @Override

  public void start() {

    System.out.println("打印机开启工作");

  }

  @Override

  public void stop() {

    System.out.println("打印机结束工作");

  }


}


JDK8中接口的使用

public interface CompareA {


  //静态方法

  public static void method1(){

    System.out.println("CompareA:北京");

  }

  //默认方法

  public default void method2(){

    System.out.println("CompareA:上海");

  }


  default void method3(){

    System.out.println("CompareA:上海");

  }

}

public class SuperClass {


  public void method3(){

    System.out.println("SuperClass:北京");

  }


}

public class SubClassTest {


  public static void main(String[] args) {

    SubClass s = new SubClass();


// s.method1();//实现类的对象不能调用接口中定义的静态方法。

// SubClass.method1();实现类也不能调用接口中定义的静态方法。


    //知识点1:接口中定义的静态方法,只能通过接口来调用,也只能调用静态方法。

    CompareA.method1();


    //知识点2:通过实现类的对象,可以调用接口中的默认方法。

    //如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法

    s.method2();


    //知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,

    //那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。-->类优先原则


    //知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,

    //那么在实现类没有重写此方法的情况下,报错。-->接口冲突。

    //这就需要我们必须在实现类中重写此方法

    s.method3();


  }


}

class SubClass extends SuperClass implements CompareA,CompareB{


  public void method2(){//实现类重写了接口中的默认方法

    System.out.println("SubClass:上海");

  }


  public void method3(){

    System.out.println("SubClass:深圳");

  }


  //知识点5:如何在子类(或实现类)的方法中调用父类、接口中被重写的方法

  public void myMethod(){

    method3();//调用自己定义的重写的方法

    super.method3();//调用的是父类中声明的

    //调用接口中的默认方法

    CompareA.super.method3();

    CompareB.super.method3();

  }

}

4.接口的应用

4.1代理模式

概述: 代理模式是Java开发中使用较多的一种设计模式。代理设计就是为其 他对象提供一种代理以控制对这个对象的访问。

public class NetWorkTest {

  public static void main(String[] args) {

    Server server = new Server();

// server.browse();

    ProxyServer proxyServer = new ProxyServer(server);


    proxyServer.browse();


  }

}

interface NetWork{


  public void browse();


}

//被代理类

class Server implements NetWork{

  @Override

  public void browse() {

    System.out.println("真实的服务器访问网络");

  }

}

//代理类

class ProxyServer implements NetWork{


  private NetWork work;


  public ProxyServer(NetWork work){

    this.work = work;

  }


  public void check(){

    System.out.println("联网之前的检查工作");

  }


  @Override

  public void browse() {

    check();


    work.browse();


  }


}

public class StaticProxyTest {

  public static void main(String[] args) {

    Proxy s = new Proxy(new RealStar());

    s.confer();

    s.signContract();

    s.bookTicket();

    s.sing();

    s.collectMoney();

  }

}

interface Star {

  void confer();// 面谈

  void signContract();// 签合同

  void bookTicket();// 订票

  void sing();// 唱歌

  void collectMoney();// 收钱

}

//被代理类

class RealStar implements Star {

  public void confer() {

  }

  public void signContract() {

  }

  public void bookTicket() {

  }

  public void sing() {

    System.out.println("明星:歌唱~~~");

  }

  public void collectMoney() {

  }

}

//代理类

class Proxy implements Star {

  private Star real;

  public Proxy(Star real) {

    this.real = real;

  }

  public void confer() {

    System.out.println("经纪人面谈");

  }

  public void signContract() {

    System.out.println("经纪人签合同");

  }

  public void bookTicket() {

    System.out.println("经纪人订票");

  }

  public void sing() {

    real.sing();

  }

  public void collectMoney() {

    System.out.println("经纪人收钱");

  }

}

4.2工厂模式

工厂方法模式

interface Car{

void run();

}

//两个实现类

class Audi implements Car{

public void run() {

  System.out.println("奥迪在跑"); 

  }

}

class BYD implements Car{

public void run() { 

  System.out.println("比亚迪在跑");

  }

}

//工厂接口

interface Factory{ 

  Car getCar();

}

//两个工厂类

class AudiFactory implements Factory{

  public Audi getCar(){ 

    return new Audi(); 

  }

}

class BydFactory implements Factory{

  public BYD getCar(){ 

    return new BYD(); 

  }

}

public class Client {

  public static void main(String[] args) {

    Car a = new AudiFactory().getCar(); 

    Car b = new BydFactory().getCar(); 

    a.run(); 

    b.run();

  }

}

你可能感兴趣的:(Java语言基础学习关键字:abstract和interface)