抽象类以及接口的区别

抽象类以及接口的区别

先来说说抽象类

抽象方法所在的类,一定是抽象类,而抽象类中未必一定要有抽象方法。
在class之前写上abstract即是抽象类。

其次是抽象方法

就是在方法名之前加入abstract关键字,然后去掉大括号,直接以分号结束。

接口中的抽象方法类型可以是任意修饰符,java8之前接口中的方法只能是public类型,java9支持private类型。

例如:

public abstract class Animal(){   //抽象类
//	抽象方法(BTW 就算没有该方法,此类还是抽象类)
	public abstract void eat();
//	普通的成员方法
	public void drink(){
		}
}

如何使用抽象类和抽象方法

1、不能直接创建new抽象类对象。
2、必须用一个子类来继承抽象父类。
3、子类必须覆盖重写抽象父类当中所有的抽象方法。(子类去掉抽象方法的abstract关键字,然后补上方法体大括号)
4、创建子类对象进行使用。
接上例:

// 子类继承抽象父类
public class Targer extends Animal(){
//子类覆盖重写父类当中的所有抽象方法
	public void eat(){
		System.out.println("吃肉");
	}
}
public class Demo(){
	public static void main(String[] args){
	//创建子类对象进行使用
		Targer targer = new Targer();
		targer.eat();  //吃肉
	}
}
注意事项

1、抽象类不能创建对象,只能创建其非抽象子类的对象。
2、抽象类中可以有构造方法是供子类创建对象时,初始化父类成员使用的。
3、抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
4、抽象类中的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非子类也是抽象类。

设计思想

抽象类是自下而上的抽象过程,抽象类提供了通用实现,是对某一类事物的抽象。我们在写实现类的时候,发现某些实现类具有几乎相同的实现,因此我们将这些相同的实现抽取出去成为抽象类,然后如果有一些差异点,则可以提供抽象方法来支持自定义实现。

错题纠正

抽象类自身可以定义成员而接口不可以 (×)

抽象类可以定义普通成员变量而接口不可以,但是抽象类和接口都可以定义静态成员变量,只是接口的静态成员变量要用public static final来修饰。

再来说说接口

接口就是多个类的公共规范。
接口是一种引用数据类型,最重要的内容就是其中的:抽象方法。

在java 7,接口中可以包含的内容:

1、常量
2、抽象方法

在java 8,接口中可以额外包含的内容:

3、默认方法
4、静态方法(不能通过接口实现类的对象来调用)

在java 9,接口中还可以额外包含的内容:

5、私有方法

在任何版本的java中,接口都能定义抽象方法。

注意事项:

1、接口当中的方法,修饰符必须是两个固定的关键字:public abstract
2、这两个关键字修饰符,可以选择性地忽略。
3、方法的三要素,可以随意定义。
例如:

public interface MyInterfaceAbstract{
//	以下都是抽象方法
	public abstract void methodAbs1();
	abstract void methodAbs2();
	public void methodAbs3();
	void methodAbs4();
	//默认方法
	public default void methodDefault(){
		System.out.println("默认方法");
	}
	//静态方法
	public static void methodStatic(){
		System.out.println("静态方法");
	}
	//接口当中也可以定义“成员变量”,但是必须使用public static final 三个关键字进行修饰。也就是接口的常量。
	/**
	注意事项:
	1、接口当中的常量,可以省略public static final
	2、接口当中的常量,必须进行赋值,不能不赋值。
	3、接口中常量的名称,使用完全大写的字母,用下划线进行分割。(推荐写法)
	**/
	public static abstract int NUM_OF_MY_CLASS = 12;
}

接口使用步骤:

1、接口不能直接使用,必须有一个“实现类”来“实现”该接口。
2、接口的实现类必须覆盖重写(实现)接口中所有的抽象方法。
实现:去掉abstract关键字,加上方法体大括号。
3、创建实现类的对象,进行使用。

注意事项:

如果实现类并没有覆盖重写接口中所有的抽象方法,那么这个实现类必须也是抽象类。

接上例
public class MyInterfaceAbstractImpl implements MyInterfaceAbstract{
//MyInterfaceAbstract的实现类,重写所有抽象方法
	@Override
	public void methodAbs1(){
		System.out.println("No.1");	
	}
	@Override
	public void methodAbs2(){
		System.out.println("No.2");	
	}
	@Override
	public void methodAbs3(){
		System.out.println("No.3");	
	}
	@Override
	public void methodAbs4(){
		System.out.println("No.4");	
	}
}
public class Demo02{
	public static void main(String[] args){
	//创建实现类的对象,进行使用
		MyInterfaceAbstractImpl impl = new MyInterfaceAbstractImpl();
		impl.methodAbs1();
		impl.methodAbs2();
		impl.methodAbs3();
		impl.methodAbs4();
		//调用默认方法,如果实现类中没有,会向上找接口
		impl.methodDefault();//输出:“默认方法”
		//impl.methodStatic();  错误写法
		//只能通过接口名称来调用静态方法
		MyInterfaceAbstract.methodStatic(); //输出:“静态方法”
		//访问接口中的常量
		System.out.println(MyInterfaceAbstract.NUM_OF_MY_CLASS); //12
	}
}

设计思想:

接口是自上而下的抽象过程,接口规范了某些行为,是对某一行为的抽象。我需要这个行为,我就去实现某个接口,但是具体怎么实现这个行为,完全是由自己决定的。

网上有一个说法挺形象的:
抽象类像叔伯,有一部分会给你,还能指导你做事的方法。
接口像干爹,可以给你指引方法,但是做成啥样得看你自己的努力成果。
普通类就是亲爹,他有啥你有啥。


版权声明:本文为weixin_38375836原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。