接口和抽象类
接口
1.接口的声明
一个接口定义一个协定。接口本身不提供它所定义的成员的实现,只指定实现该接口的类必须提供的成员,继承接口的任何非抽象类型都必须实现接口的所有成员。
接口类似于抽象基类,不能实例化。接口中声明的所有成员方法隐式地为 public 和 abstract。接口可以包含抽象方法和静态常量字段。接口声明的语法与类声明的语法类似。
2.接口的成员
接口通常是公共契约,故一个接口可以声明零个或多个成员,但只能包含其成员的签名。接口的成员包括从基接口继承的成员和由接口本身声明的成员。接口成员只能包含抽象方法和静态常量字段。
接口的成员变量默认为静态常量字段(public static final),但接口的成员变量不能带除public static final 以外的任何修饰符。
接口的成员方法默认为公共抽象方法(public abstract ),但接口的成员方法不能带除public abstract 以外的任何修饰符。因为默认为公共抽象方法(public abstract),所以建议不要带任何修饰符。
3.接口的实现
接口可以由类来实现。为了指示类实现了某接口,在该类或结构的基类列表中应该包含该接口的标识符。派生类使用关键字implements指定要实现的基接口列表。派生类实现接口的声明形式如下:
[类修饰符] class 类名 [implements]{
类体;
}
4.接口的继承
接口可以从零个或多个接口继承,被继承的接口称为该接口的基接口。接口使用关键字 extends 指定要继承的接口。接口继承声明的基本形式如下:
[接口修饰符] interface 接口名 [extends 基接口列表]{
类体;
}
接口的成员包括从基接口继承的成员和由接口本身声明的成员,故实现该接口的类必须实现接口本身声明的成员以及该接口从基接口继承的成员。
接口继承的示例:模拟银行/存取款
/**
* 描述:模拟银行/存取款
*
* @Author administrator{GINO ZHANG}
* @Date2018/11/18
*/
interface IBankAccount{ //银行账户
void payIn(double amount); //存款
boolean withdrow(double amount); //取款,并返回是否成功
double getBalance(); //余额
}
interface ITransferBankAccont extends IBankAccount{ //转账银行账户
boolean transferTo(IBankAccount destination,double amount);
}
class CurrentAccount implements ITransferBankAccont{
public String name;
private double balance;
public CurrentAccount(String name){
this.name = name;
}
public void payIn(double amount){ //存款
this.balance += amount;
}
public boolean withdrow(double amount){
if (this.balance >= amount){
this.balance -= amount;
return true;
}
System.out.println("余额不足,取款失败!");
return false;
}
@Override
public double getBalance() { //返回余额
return this.balance;
}
@Override
public boolean transferTo(IBankAccount dest, double amount) {
boolean result;
if ((result = withdrow(amount)) == true)
dest.payIn(amount);
return result;
}
@Override
public String toString() {
return String.format("账户(%s):余额 = %9.2f",this.name,this.balance);
}
}
public class InterfaceInheritDemo {
public static void main(String[] args) {
IBankAccount bankCount1 = new CurrentAccount("张三");
ITransferBankAccont bankCount2 = new CurrentAccount("李四");
bankCount1.payIn(200);
bankCount2.payIn(500);
bankCount2.transferTo(bankCount1,100);
System.out.println(bankCount1.toString());
System.out.println(bankCount2.toString());
}
}
运行结果:
C:\java\java7\jdk1.7.0_80\bin\java.exe -javaagent:D:\ideaIU-2018.1.5.win\lib\idea_rt.jar=39322:D:\ideaIU-2018.1.5.win\bin -
账户(张三):余额 = 300.00
账户(李四):余额 = 400.00
Process finished with exit code 0
抽象类和抽象方法
1.抽象类(abstract class)
将将关键字abstract置于关键字class前面可以将类声明为抽象类。抽象类不能实例化。抽象类一般用于提供多个派生类可共享的基类的公共定义。例如:类库可以定义一个包含基本功能的抽象类,并要求程序员在使用该类库时,通过创建派生类来提供自己的类实现。
抽象类与非抽象类相比,有以下的特点:
(1)抽象类不能直接实例化,对抽象类使用new运算符会导致编译错误。可以定义抽象类型的变量,但其值必须为null,或者是去派生类的非抽象类的实例的引用。
(2)允许(但不要求)抽象类包含抽象成员。
(3)抽象类不能被密封。
(4)当从抽象类派生非抽象类时,这些非抽象类必须实现所继承的所有抽象成员,从而重写哪些抽象成员。
2.抽象方法(abstract method)
在抽象类中通过将关键字abstract 添加到实例方法的返回类型的前面定义抽象方法。抽象方法声明引入一个新的虚方法,但不提供该方法的任何实际的实现,所以抽象方法的方法体只由一个分号组成,而不是常规的方法块。
除了构造方法、静态方法和私有方法不能声明为抽象方法外,其他任何方法都可以声明为抽象方法。
注意点:
1.抽象类不能实例化,实例化的工作由子类完成,它只需要一个引用
2.抽象方法必须由子类重写
3.只包含一个抽象方法的类,必须要的定义成抽象类
4.抽象类可以包含具体方法,也可以不包含具体的抽象方法
5.abstract 不能与final并列修饰类
6.abstract 不能与private、static、final、native并列修饰方法
代码演示:
/**
* 描述:抽象类和抽象方法演示
*
* @Author administrator{GINO ZHANG}
* @Date2018/11/18
*/
abstract class Animal{ //声明一个抽象基类
public String name;
public abstract void sayHello(); //抽象类可以声明抽象方法
public Animal (String name){
this.name = name;
}
public String getName() { //抽象类可以声明非抽象方法
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Dog extends Animal{ //派生类 Dog
public void sayHello(){ //重写 sayHello()
System.out.println(this.name + ":Wow Wow!");
}
public Dog(String name){
super(name);
}
}
class Cat extends Animal{
public void sayHello(){
System.out.println(this.name + ":Mew Mew!");
}
public Cat(String name){
super(name);
}
}
abstract class Fish extends Animal{ //派生类 Fish
public Fish(String name){ //重写 sayHello()
super(name);
}
}
public class AbstractDemo {
public static void main(String[] args) {
//Animal animal1 =new Animal(); //编译错误,抽象类不能直接实例化
Animal animal1 = new Dog("小白");
animal1.sayHello();
Dog dog1 = new Dog("小黑");
dog1.sayHello();
Cat cat1 = new Cat("小花");
cat1.sayHello();
}
}
运行结果:
C:\java\java7\jdk1.7.0_80\bin\java.exe -javaagent:D:\ideaIU-2018.1.5.win\lib\idea_rt.jar=29034:D:\ideaIU-2018.1.5.win\bin
小白:Wow Wow!
小黑:Wow Wow!
小花:Mew Mew!
Process finished with exit code 0
接口和抽象类的区别
1.只能继承一个抽象类,但可以实现多个接口;
2.抽象类里面定义的成员变量,可以使任何类型的变量;接口定义的成员变量,默认是 public static final类型的常量;
3.抽象类里面可以实现方法;接口的方法不能,而且默认都是 public abstract 类型的方法;
4.继承抽象类,一般表示父类和子类之间是:is a … 的关系;实现接口,一般表示 has a… 。