一、抽象类和抽象方法

  abstract修饰符修饰的方法称为抽象方法,修饰的类称为抽象类。

1、抽象类和抽象方法的关系

抽象类中可以没有抽象方法,但是有抽象方法的类一定要申明为抽象类。

2、语法

public abstract class Action{
    public abstract void doSomething();
}


对于一个普通方法public void doSomething(){...}来说,

public void doSomething()这一部分是方法的申明

{...}这部分是方法的实现,如果大括号中什么都不写,就叫方法的空实现

对于一个抽象方法,abstract修饰符合{...}不能同时出现,会编译报错

3、特点及作用

抽象类,不能使用new关键字来创建对象,它是用来让子类继承的

抽象方法,只有方法的申明,没有具体的方法实现,他是用来让子类实现的

 

:子类继承抽象类后,需要实现抽象类中没有实现的抽象方法,否则这个子类也要声明为抽象类。

例如:

public abstract class Action{
    public abstract void doSomething();
}

public static void main(String[] args){
    //编译报错,抽象类不能new对象
    Action a = new Action();
}
 
//子类继承抽象类
public class Eat extends Action{
    
    //实现父类中没有实现的抽象方法
    public void doSomething(){
    //code
    }
}
 
public static void main(String[] args){
    Action a = new Eat();
    a.doSomething();
}

     注:子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。

 

    思考:抽象类有没有构造方法?

       答:抽象类也是类,抽象类的构造方法和普通类的构造方法一样,都是用来初始化类,只是抽象类

     的构造方法不能直接调用,因为抽象类不能实现实例。但是如果一个普通类继承了抽象类,便可以在构造

     函数中调用抽象类的构造函数。

 

二、接口

  1、申明

public interface Action{

}

 

  2、接口和抽象类的区别

        A) 抽象类也是类,除了可以写抽象方法以及不能直接new实例对象外,其他方面和正常类没什么区别。

        B) 接口是另一种类型,和类有本质上的区别,所以不要用类的标准衡量接口。

        C) 申明类的关键字是class,申明接口的关键字十interface

        D) 抽象类是用来被继承的,java中的类是单继承,继承的关键字是extends

        E) 接口是用来被实现的,java中的接口可以被多实现,实现的关键字是implements

  3、接口中的变量都是静态常量(public static final修饰)

   接口中可以不写任何属性,但是如果写属性了,该属性必须是public static final修饰的静态常量。

   当然, 在调用给的时候可以直接使用接口名访问其属性,因为是public static修饰的。例如:


public interface Action{
    public static final String NAME = “tom”;
    //默认就是public static final修饰的
    int AGE = 20;
}
 
public static void main(String[] args){
    System.out.println(Action.NAME);
    System.out.println(Action.AGE);
}

  4、接口中的方法都是抽象方法

    接口中可以不写任何方法,但是如果写方法了,该方法必须是抽象方法。

    例如:


public interface Action{
    public abstract void run();
    //默认就是public abstract修饰的
    void test();
    public void go();
}

  5、一个类可以实现多个接口


public class Student implements A,B,C,D{
   //Student需要实现接口A B C D中所有的抽象方法
   //否则Student类就要声明为抽象类
}
public static void main(String[] args){
   A s1 = new Student();
   B s2 = new Student();
    C s3 = new Student();
    D s4 = new Student();
}


    注:
     s1只能调用接口A中声明的方法以及Object中的方法
     s2只能调用接口B中声明的方法以及Object中的方法
     s3只能调用接口C中声明的方法以及Object中的方法
     s4只能调用接口D中声明的方法以及Object中的方法
    但是如果在申明s1、s2、s3、s4的时候全部申明为Student类型,那么他们可以互相调用各自的方法

  

     注:必要时可以类型强制转换
     例如:
       接口A 中有test()
       接口B 中有run()

       A s1 = new Student();

       B s2 = new Student();

       s1.test();

       s2.run();
            
       if(s1 instanceof B){
          ((B)s1).run();
        }

  6、一个接口可以继承多个父接口


 public interface A{
    public void testA();
  }
 public interface B{
    public void testB();
 }
        
 //接口C把接口A B中的方法都继承过来了
 public interface C extends A,B{
    public void testC();
 }
        
 //Student相当于实现了A B C三个接口,需要实现所有的抽象方法
 //Student的对象也就同时属于A类型 B类型 C类型
 public class Student implements C{
    public viod testA(){}
    public viod testB(){}
    public viod testC(){}
  }
  
 public static void main(String[] args){
    C o = new Student();
    System.out.println(o instanceof A);//true
    System.out.println(o instanceof B);//true
    System.out.println(o instanceof C);//true
    System.out.println(o instanceof Student);//true
    System.out.println(o instanceof Object);//true
    System.out.println(o instanceof Teacher);//false
    //编译报错
    System.out.println(o instanceof String);
 }

    注:
    System.out.println(o instanceof X);
    如果o是一个接口类型声明的变量,那么只要X不是一个final修饰的类,该代码就能通过编译,至于其结果是不是 true,就要看变量o指向的对象的实际类型,是不是X的子类或者实现类了。
    注:一个引用所指向的对象,是有可能实现任何一个接口的。(java中的多实现)