Java 抽象与接口

什么是抽象类与抽象方法

如果父类中的方法不确定如何进行方法体实现,那么就可以把这个方法定义为一个抽象方法。

(例如在宠物叫声实验里,在pet类中 因为不能确定子类的叫声,所以用的空方法)

用关键字abstract修饰的类称为抽象类。 例如:

abstract class Pet {

}

用关键字abstract修饰的方法成为抽象方法。对于抽象方法,只允许声明,不允许实现,即抽象方法只有方法声明,而没有方法体。

abstract class Pet {
    public abstract void cry();

}

(1)抽象类可以包含抽象方法
抽象类可以包含普通类能够包含的任何东西,例如非抽象方法、成员变量等,此外还可以有抽象方法。
(2)抽象类也可以没有抽象方法
包含抽象方法的类一定是抽象类(必须用abstract修饰),即只有抽象类才能具有抽象方法;
未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。
(3)抽象类不能使用new关键字创建对象,即抽象类不能直接实例化,只能创建其非抽象子类的对象;

  (4)抽象类必须用一个子类来继承抽象父类;
(5)子类必须覆盖重写抽象父类当中所有的抽象方法,除非该子类也是一个抽象类。
(6)抽象类不能使用final修饰,抽象方法也不能使用final修饰。

抽象类概述

1、什么是抽象类与抽象方法
用关键字abstract修饰的类称为抽象类。
用关键字abstract修饰的方法称为抽象方法。
2、抽象类的特点
抽象类可以包含抽象方法也可以不包含抽象方法。
抽象类不能直接实例化。
抽象类必须有子类继承并且子类必须覆写所有的抽象方法。
抽象类不能使用final修饰,抽象方法也不能使用final修饰。
3、抽象类的作用
可以使程序的设计者把主要精力放在程序的设计上,而不必拘泥于细节的实现上

abstract class Pet {
    private String name,color,breed;
    //构造方法省略
    public abstract void cry(); //抽象方法
    public void drink() { //普通方法
        Ststem.out.println("喝水");
}

}

抽象类不能像普通类那样直接实例化对象。
如果一个类是某个抽象类的非抽象子类,那么它必须重写父类的全部抽象方法(给出方法体)。
可以实例化并使用一个抽象类的非抽象子类对象

class Dog extends Pet {
    //构造方法省略
    public void cyr();{ //子类必须重写父类的cry方法

        System.out.println("wangwangwang")

    }
}
public class TestExample {
       public static void main(String args[]) {
                 Dog dog=new Dog(“乐乐”, “棕色”, “吉娃娃”);
              dog.cry();         //调用重写的方法
              dog.drink();           //调用继承的方法
       }
}

接口

接口,是Java语言中的一种引用类型,是方法的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
接口是一种特殊的类;
接口是解决Java无法使用多继承的一种手段,但是接口在实际中更多的作用是指定标准的;
接口使抽象的概念更深入了一层,可将其想象为一个“纯”抽象类。

使用规范:

(1)不能对接口直接进行对象的实例化操作;
(2)接口中只有全局常量,没有成员变量,所以接口中不能有构造方法;
(3)每一个接口必须定义子类,子类使用implements关键字实现接口;
(4)接口的实现类(如果不是抽象类)必须重写接口中所定义的全部抽象方法;
(5)一个接口可以继承扩展多个父接口;
(6)一个类可以实现多个接口。
(7)利用接口的子类,采用对象的向上转型方式,进行接口对象的实例化操作。

定义

接口的定义和类的定义很相似,分为接口的声明和接口体。
接口必须使用interface来声明,格式:

public interface 接口名称 {
    //接口内容
}

成员变量:

其实就是接口的常量
语法格式:

public static final 数据类型 常量名称 = 数据值;
注意:
可以省略public、static、final,但是不写也默认是这样的;
常量必须进行赋值,而且一旦赋值不能改变;
常量名称完全大写,用下划线进行分隔。

抽象方法

语法格式:

public abstract 返回值类型 方法名称(参数列表);
注意:
接口当中的抽象方法,修饰符必须是两个固定的关键字:public、abstract;
这两个关键字修饰符,可以选择性的忽略;
方法的三要素,可以随意定义。

接口使用步骤

(1)接口不能直接用来创建对象,必须有一个“实现类”来“实现”该接口。
(2)接口的实现类必须覆写(实现)接口中所有的抽象方法。
(3)使用接口时,通过创建实现类的对象,进行使用。

一个类通过使用关键字implements声明自己实现接口,这个类称为实现类,语法格式:

 public class 实现类名称 implement 接口名 {

    .....

}

一个类可以实现多个接口,需要用逗号接接口名隔开。语法格式为:

class 类名 implement  接口1,接口2,......{

    .....

}

抽象类方法的实现

如果一个非抽象类实现了一个或多个接口,则该类必须实现该接口或所有接口的所有抽象方法。

在重写接口方法时不仅要去掉abstract修饰符,给出方法体;而且遵循类中关于继承的语法规则,即重写后方法的访问权限一定要明显地使用public来修饰,否则会降低访问权限(不允许)。
如果实现类所实现的多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可。
如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类。

 阅读以下代码,熟悉接口的使用 

//两个接口
interface Charging{  //  收费
    public void charge();  // 收取费用
}
interface  Attemperation {  // 调节温度
   public void  controlTemperature();
}
class Bus implements Charging { // 公共汽车
   public  void charge() { 
       System.out.println("公共汽车:一元/张,不计算公里数"); //在实现类中重写该抽象方法
    }
}
class Taxi implements Charging,  Attemperation {  //出租车    //实现两个接口
      public void charge() {
             System.out.println("出租车:3.20元/公里,起价3公里");  //重写两个接口的抽象方法
      }
      public void  controlTemperature() {
             System.out.println("安装了Hair空调");
      }
}
class MovieTheater implements Charging,  Attemperation {  //  电影院
      public void charge() {
             System.out.println("电影院:门票,十元/张");
      }
      public void  controlTemperature() {
             System.out.println("安装了中央空调");
      }
}
public class TestInterface {
      public static void main(String args[]) {
             Bus  busNo7 = new Bus();        Taxi taxiTianyu = new Taxi();
             MovieTheater mTheaterHongxing = new MovieTheater();
             busNo7.charge();         taxiTianyu.charge();  
             mTheaterHongxing. charge();  
             taxiTianyu.controlTemperature();
             mTheaterHongxing.controlTemperature();
    }
}

接口的使用

默认方法的使用:

[public]   default  返回值类型  方法名称(参数列表){
    方法体
};

接口的默认方法,可以通过接口的实现类直接调用;
接口的默认方法,也可以被接口实现类进行覆盖重写。
如果实现类实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆写。
静态方法的使用:

[public]   static  返回值类型  方法名称(参数列表){
    方法体
};

不能通过实现类的对象来调用接口当中的静态方法,需要通过接口,直接调用其中的静态方法,语法格式:

接口名称.静态方法名(参数)
私有方法:私有方法只有接口自己才能调用,不能被实现类或别人使用。

private  返回值类型  方法名称(参数列表){
    方法体
};

接口支持继承,也支持多重继承

interface 接口名称 extends 接口1,接口2,...{

.....

}

接口继承也是使用extends关键字。
继承的接口方法仍旧是public与abstract的。
如果父接口中的接口方法有重复,则进行归并

一个类可以在继承某个类(只能一个,而且可以是抽象类)的同时实现一个或多个接口。例如:

Class Dog extends Pet implements Eatable, Sleepable {

.......

}//Dog类在继承父类Pet的同时实现Eatable和Sleepable两个接口

注意:implemets如果存在的话必须在最后,不能在extends前。

需要注意以下几点:
声明接口时,如果在关键字interface前面加上public关键字,就称这样的接口是一个public接口,它可以被任何一个类声明实现;否则,如果没有加上public,它只能被与该接口在同一个包中的类声明实现;
 如果父类实现了某个接口,那么其子类也就自然实现了该接口;
 接口也可以被继承(仍通过关键字extends声明),子接口将继承父接口中的所有方法和常量。
 如果一个类声明实现某个接口,但没有重写接口中的所有方法,则该类必须是抽象类。

适配器类

由于类实现接口,必须实现所有的接口方法,这对程序员很不方便,Java语言中提出了适配器的概念来解决。
所谓适配器就是实现接口,并对接口中的接口方法提供空实现。
空实现就是有方法体,但方法体中基本上不提供任何有效代码。 例如:

interface  IBiz {   //接口 
  	void  charge();
	boolean withdraw(double  amount);   
  }
class  BizAdapter implements  Ibiz{   //适配器类 
	public void charge()  {  } 
	public boolean withdraw(double amount){
		return false;
	}
  }  
class BizImpl  extends BizAdapter{
           //通过适配器值需要实现需要的接口方法 
  	 public void charge(){
		……	//接口方法的真正实现。 
	}
  }

接口与多态

接口回调

接口回调是通过接口实现多态性的核心机制。
接口回调,是指把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类重写的接口方法。
实际上,当接口变量调用被类重写的接口方法时,就是通知相应的对象调用这个方法。
接口回调非常类似前面介绍的上转型对象调用子类的重写方法。

interface  ShowMessage {
       void show(String s);
}
class TV implements ShowMessage {
      public void show(String s) { 
           System.out.println(“TV商标:” + s);  
      }
}
class PC implements ShowMessage {
      public void show(String s) {  
          System.out.println("PC商标:" + s ); 
      }
}
public class TestInterface {
   public static void main(String args[]) {
      ShowMessage sm;                  //声明接口变量
      sm=new TV();                          //接口变量中存放对象的引用
      sm.show("长城牌电视机");        //接口回调。
      sm=new PC();                          //接口变量中存放对象的引用
      sm.show("联想奔月5008PC机"); //接口回调
   } 
}

接口与多态

接口是实现多态的重要途径之一。
由接口产生的多态就是不同的类在实现同一个接口时可能具有不同的实现方式,那么接口变量在回调接口方法时就可能具有多种形态。
一个接口只有方法的特征,没有方法的实现,所以这样的方法可以在不同的地方,被不同的类实现,因而这些实现可以具有不同的行为或功能。

利用接口也可以体现程序设计的所谓“开-闭”原则(Open-Closed Principle),即强调一个程序应当对扩展开放,对修改关闭,增强代码的可维护性。

案例

设计一个广告牌,希望广告牌上可以显示不同公司的名称和广告词。

public interface Advertisement {
    public void showAdvertisement();           //接口 提供获取公司名称和广告词的方法
    public void getCorpName();
}
public class AdvertisementBoard {
    public void show(Advertisement adver) {         //广告牌累 提供一个方法show 显示广告牌信息
        System.out.println(adver.getCorpName()+"公司广告词:");
        adver.showAdvertisement();
    }
}
public class IntelCorp impllements Advertisement {
    public void showAdvertisement() {        //实现接口的Intel类 
        System.out.println("@@@@@@@@@@");
        System.out.println("给电脑一颗奔腾的芯");      //实现类需要对接口中所有抽象方法重写
        System.out.println("@@@@@@@@@@");
    }
    public String getCorpName() {
        return "英特尔";
    }
}
public class HuaweiCorp implement Advertisement {
    public void showAdvertisement() {
        System.out.println("***********");
        System.out.println("丰富人们的沟通与生活");
        System.out.println("***********");
    }
    public String getCorpName() {
        return "华为";
    }
}
public class Testlnterface {
    public static void main(String arges[]) {
        AdvertisementBoard board = new AdvertisementBoard();
        board.show(new IntelCorp());       //接口与回调
        board.show(new HuaweiCorp());
    }
}

接口小结

1.如果一个类定义时全部由抽象方法和全局常量(可以没有)组成,那么这种类就称为接口;
2.接口使用interface定义,分为接口的声明和接口体,接口体则包含常量定义(可以没有)和方法定义两部分;
3.接口中的所有常量的访问权限一定都是public,而且允许省略public、final和static修饰符;
4.接口中的所有方法都是抽象方法,没有普通方法,其访问权限一定都是public,而且允许省略public、abstract修饰符;
5.接口支持多重继承,一个接口可以继承自多个父接口;
6.一个类通过使用关键字implements声明自己实现一个或多个接口;

7.一个类可以在继承某个类(只能一个,而且可以是抽象类)的同时实现一个或多个接口;
8.接口可以实现与类的多重继承同样强大的功能;
9.接口回调,是指把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类重写的接口方法;
10.由接口产生的多态就是不同的类在实现同一个接口时可能具有不同的实现方式,那么接口变量在回调接口方法时就可能具有多种形态。
11.接口只关心操作,并不关心操作的具体实现 ,我们可以把主要精力放在程序的设计上,而不必拘泥于细节的实现。

 接口类与抽象类的联系与比较

共同点:
都有抽象的行为,约束了它们的实现者(类)或者子类必须实现的业务功能。
接口中的所有行为都是抽象行为;
抽象类通常都有抽象行为。
不同点:
抽象类与其子类从大的范畴来讲它们属于同一类型(或同一种事物),抽象行为也决定了它的所有子类应该具有的行为。因此,抽象类是对属于同一种类型的不同事物的共同行为的一种抽象或表达;
接口中的抽象行为可以被任何类实现,实现这个接口的类可以是不同的类(这些类之间毫无关系)。因此,接口是对不同种类型的事物的共同行为的一种抽象。

实现接口的类可以是抽象类,即该实现类并未实现接口中的全部抽象方法。

一个非抽象类可以通过继承实现接口的某个抽象类,来方便地实现接口的功能。

抽象类除了提供重要的需要子类去实现的抽象方法外,还提供了子类可以继承的变量和非抽象方法。如果某个问题需要使用继承才能更好地解决,就可以考虑用抽象类。如果某个问题的解决不需要继承,只是需要若干个类给出某些重要的抽象方法的实现细节,就可以考虑使用接口。
在实际开发中,为了避免单继承的局限,当遇到抽象类和接口都可以使用的情况下要优先考虑使用接口。

JDK常用接口

猜你喜欢

转载自blog.csdn.net/CYwxh0125/article/details/127455137