java抽象类与接口小结及区别

为了强制要求子类必须覆写父类方法产生了抽象类与接口。

一、抽象类
1.定义:抽象类是普通类的超集,只是比普通类多了一些抽象方法。
抽象方法:使用abstract关键字定义的只有方法声明没有方法体的方法。

public abstract void test();

抽象类中包含抽象方法,则抽象类也必须使用abstract来定义,表示抽象类。

不是所有的只有方法声明没有方法体的方法都是抽象方法。
本地方法(Java调用C同名方法):使用native定义的只有方法声明没有方法体的方法。
public native int hashCode();

2.抽象类的使用限制
所有抽象类必须有子类(所以final与abstract不能同时出现)
抽象类的子类必须覆写所有抽象方法(子类也使用abstract关键字定义)
priavte与abstract不能同时出现,抽象方法必须被覆写而privtae方法无法被覆写

abstract class Person{
   private String name;//属性
   public String getName(){//普通方法
      return this.name;
   }
   public void setName(String name){
      this.name=name;
   }
   public abstract void getPersonInfo();//抽象方法
}
class Student extends Person{
   public void getPersonInfo(){
      System.out.println("I am a student");
   }
}
public class Test{
   public static void main(String[] args){
   Person per=new Student();//实例化子类,向上转型
   per.getPersonInfo();//被子类所覆写的方法
   }
}

抽象类无法直接产生实例化对象,但可以通过子类向上转型进行实例化。且子类依然遵循对象实例化流程,先调用抽象类构造方法而后再调用子类构造。

abstract class Person{
   private String name;//属性
   public Person(){//构造方法
      System.out.println("**********");
   }
   public String getName(){//普通方法
      return this.name;
   }
   public void setName(String name){
      this.name=name;
   }
//{}为方法体,所有抽象方法上不包含方法体
   public abstract void getPersonInfo();//抽象方法
}
class Student extends Person{
   public Student(){//构造方法
      System.out.println("##########");
   }
   public void getPersonInfo(){
   //空实现。
   }
}
public class Test{
   public static void main(String[] args){
   new Student();
   }
}

如果父类无无参构造,子类构造中应使用super关键字明确指出调用的是哪个构造方法。

abstract class A{
   public A(){//3.调用父类构造
      this.print();//4.调用被子类覆写的方法
   }
   public abstract void print();
}
class B extends A{
   private int num=100;
   public B(int num){//2.调用子类实例化对象
      super();//3.隐含一行语句,实际要先调用父类构造
      this.num=num;//7.为类中属性初始化
   }
   public void print(){//5.此时子类对象的属性还没有被初始化
      System.out.println(this.num);//6.对应其数据类型的默认值
   }
}
public class Test{
   public static void main(String[] args){
      newB(30);//1.实例化子类对象
   }
}

抽象类可以没有抽象方法,但是此时仍然不能直接实例化对象。

二、接口

开发原则:接口优先原则,在一个场景既可以使用抽象类也可以使用接口的时候,优先考虑使用接口。

1.定义:接口中只有全局常量和抽象方法(JDK8之前),接口使用interface定义接口。

interface Imessage{
    public static final String MSG="hello";//全局常量
    public abstract void print();//抽象方法
}

阿里编码规约:接口中的方法和属性不要加任何修饰符,public也不要加,保持代码简洁性。

interface IMessage{
    String MSG="hello";//全局常量
    void print();//抽象方法
}

2.使用原则:
接口无法直接创建实例化对象,需要通过具体子类向上转型为其实例化

IMessage m=new MessageImp();

接口命名一般以I开头,子类使用implements关键字实现接口,一般以impl结尾,表示此类是一个接口的子类
接口允许多实现(多继承),一个子类可以同时使用implements实现若干个接口
接口中只允许public权限!即便不写也是public,接口中abstract、final、static均可以省略不写。(强制要求不写)
当子类既需要继承抽象类又需要实现接口时,先extends一个抽象类而后使用implements实现多个接口
抽象类可以使用implements实现多个接口,接口不能继承抽象类,接口可以使用extends继承多个父接口

interface IMessage{
   void print();
}
abstract class News implements IMessage{
//News为抽象类,可以不实现IMessage中的抽象方法
//抽象类中方法前面的abstract不能省略,否则就是普通方法
   public abstract void getNews();
}
class MessageImpl extends News{
   public void print(){
      System.out.println("***");
   }
   public void getNews(){
      System.out.println("I am News");
   }
}
public class Test{
   public static void main(String[] args){
      IMessage m=new MessageImpl();
      m.print();
//MessageImpl是抽象类和接口的共同子类
      News news=(News)m;
      news.getNews();
   }
}

3.接口应用场景
定义操作标准(USB接口 Type—c接口 5G标准等)

interface USB {
    public void setup() ; // 安装USB驱动
    public void work() ; // 进行工作
}

表示一种能力、行为
在分布式开发之中暴露远程服务方法

接口与抽象类的区别:

java抽象类与接口小结及区别