abstract class
声明方法的存在而不去实现它的类被叫做抽象类,使用abstract 声明类,它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。
不能创建抽象类的实例(不能使用new创建对象)。然而抽象类可以定义变量,引用具体子类的实例(对象)。
不能有抽象构造函数或抽象静态方法。
抽象类只能被继承,在具体子类中必须实现全部抽象方法。
案例:
package day03;
public class abstracClassDemo {
public static void main(String[] args){
//Shape s = new Shape();//抽象类不能直接实例化(不能使用new创建对象)
Shape s = new Circle(3,4,5);
s.down();
System.out.println(s.contains(3, 4));
}
}
abstract class Shape{//抽象的图形,使用abstract 声明类
int x;
int y;
public abstract boolean contains(int x,int y);//抽象类可以保护抽象方法,使用abstract声明的方法,抽象方法不能有方法体
public void down(){//可以包含非抽象类方法
y++;
}
}
abstract class square{
public square(){//抽象类中可以有构造函数
}
public abstract boolean around();
}
//实现抽象类用extends,抽象类只能被继承,在具体子类中必须实现全部抽象方法
class Circle extends Shape /*extends square*/{//一个类只能继承一个抽象类。
int r;
public Circle(int x,int y,int r){
this.x = x;
this.y = y;
this.r = r;
}
public boolean contains(int x, int y) {
int a = this.x - x;
int b = this.y - y;
return Math.sqrt(a*a+b*b)<=r;
}
}
interface
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
案例一:
package day03;
public class interfaceDemo01 {
public static void main(String[] args){
Runner tt=new TT();//接口的引用指向实现的对象
System.out.println(tt.i);
System.out.println(Runner.i);
tt.start();
Eater ee=new TT();
System.out.println(ee.j);
System.out.println(Eater.j);
ee.start();
Drinker dd=new TT();
dd.getWater();
dd.drinkWater();
}
}
//定义接口
interface Runner{
//int i;//必须初始化
int i=3;
//i = i+1;//接口中定义的变量只能是public static final类型,并且默认即为public static final类型,不可以再改变。
public void start();
void run();
void stop();
/*接口中不能含有非抽象类
public void down(){//可以包含非抽象类方法
y++;
}
*/
/*接口中不能有构造函数
public Runner(){
}
*/
}
//接口间可以继承
interface Eater extends Runner{
public static int j=4;
//private int i= 1;//接口中不能含有私有变量
void openMouth();
void upAndDown();
void goIn();
}
interface Drinker{
void getWater();
void drinkWater();
}
//引用接口用implements
class TT implements Eater,Drinker{//一个类可以实现多个接口
public void start(){
System.out.println("---------start()-------");
}
public void run(){
System.out.println("---------run()-------");
}
public void stop(){
System.out.println("---------stop()-------");
}
public void openMouth(){
System.out.println("---------openMouth()-------");
}
public void upAndDown(){
System.out.println("---------upAndDown()-------");
}
public void goIn(){
System.out.println("---------goIn()-------");
}
public void getWater() {
System.out.println("---------getWater()-------");
}
public void drinkWater() {
System.out.println("---------drinkWater()-------");
}
}
案例二:
package day03;
public class interfaceDemo02 {
public static void main(String[] args){
CareAnimalable c = new Worker();
//Worker w = (Worker)c;
interfaceDemo02 t = new interfaceDemo02();
t.t(c); //多态
c = new Farmer();
t.t(c);
}
public void t(CareAnimalable c){//尽量定义为接口或父类的引用
c.feed();
c.play();
}
}
//定义一个接口
interface CareAnimalable{
public void feed();
public void play();
}
class Worker implements CareAnimalable{
public void feed(){
System.out.println("-----feed()----");
}
public void play(){
System.out.println("-----play()----");
}
}
class Farmer implements CareAnimalable{
public void feed(){
System.out.println("-----Farmer feed()----");
}
public void play(){
System.out.println("-----Farmer play()----");
}
}
区别
下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
3.抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
4.抽象类中可以包含静态方法,接口中不能包含静态方法
5.抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
6.一个类可以实现多个接口,但只能继承一个抽象类。
7.尽管interface实现类及abstrct class的子类都必须要实现相应的抽象方法,但实现的形式不同。interface中的每一个方法都是抽象方法,都只是声明的 (declaration, 没有方法体),实现类必须要实现。而abstract class的子类可以有选择地实现。
这个选择有两点含义:
一,是abastract class中并非所有的方法都是抽象的,只有那些冠有abstract的方法才是抽象的,子类必须实现。那些没有abstract的方法,在Abstrct class中必须定义方法体。
二,是abstract class的子类在继承它时,对非抽象方法既可以直接继承,也可以覆盖;而对抽象方法,可以选择实现,也可以通过再次声明其方法为抽象的方式,无需实现,留给其子类来实现,但此类必须也声明为抽象类。既是抽象类,当然也不能实例化。
8.abstract class是interface与Class的中介。
interface是完全抽象的,只能声明方法,而且只能声明pulic的方法,不能声明private及protected的方法,不能定义方法体,也 不能声明实例变量。然而,interface却可以声明常量变量,并且在JDK中不难找出这种例子。但将常量变量放在interface中违背了其作为接 口的作用而存在的宗旨,也混淆了interface与类的不同价值。如果的确需要,可以将其放在相应的abstract class或Class中。
abstract class在interface及Class中起到了承上启下的作用。一方面,abstract class是抽象的,可以声明抽象方法,以规范子类必须实现的功能;另一方面,它又可以定义缺省的方法体,供子类直接使用或覆盖。另外,它还可以定义自己 的实例变量,以供子类通过继承来使用。