抽象方法、抽象类、接口、接口和抽象类的区别

抽象类、抽象方法

某个父类只知道子类因该包含什么样的方法,无法知道这些子类如何实现这些方法。抽象类包含该方法但没有对该方法的具体实现。

有抽象方法的类只能被定义为抽象类,抽象类里可以没有抽象方法。

抽象方法和抽象类的规则:

  • 抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰抽象方法不能有具体的方法体
  • 抽象类不能被实例化,无法使用new关键字来调用抽象类构造器创建抽象类的实例。即使抽象类里不包含抽象方法,这个抽象类也不能创建实例
  • 抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。
  • 抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要用于被其子类调用
  • 含有抽象方法的类(包括直接定义了一个抽象方法;或继承了一个抽象父类,但没有完全实现父类包含的抽象方法;或实现了一个接口,但没有完全实现接口包含的抽象方法的三种情况)只能被定义成抽象类。
public abstract class Shape {
	{
		System.out.println("执行Shape的初始化块...");
	}
	private String color;
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	//定义一个计算周长的抽象方法
	public abstract double cal();
	//定义一个返回形状的方法
	public abstract String getType();
	//定义Shape的构造器,该构造器并不是用于创建Shape对象
	//而是用于被子类调用
	public Shape(String color){
		System.out.println("执行shape的构造器...");
		this.color=color;
	}
	    
}
public class Triangle extends Shape{
    private double a;
    private double b;
    private double c;
    public Triangle(String color,double a,double b,double c) {
		// TODO Auto-generated constructor stub
    	super(color);
    	this.setSides(a, b, c);
	}
    public void setSides(double a,double b,double c){
    	if(a>=b+c||b>=a+c||c>=a+b){
    		System.out.println("三角形的两边之和必须大于第三边");
    		return;
    	}
    	this.a=a;
    	this.b=b;
    	this.c=c;
    }
	@Override
	public double cal() {
		// TODO Auto-generated method stub
		return a+b+c;
	}

	@Override
	public String getType() {
		// TODO Auto-generated method stub
		return "三角形";
	}

}
public class Circle extends Shape {
	private double radius;
	public Circle(String color,double radius) {
		super(color);
		// TODO Auto-generated constructor stub
		this.radius =radius;
	}
	
	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}

	@Override
	public double cal() {
		// TODO Auto-generated method stub
		return 2*Math.PI*radius;
	}

	@Override
	public String getType() {
		// TODO Auto-generated method stub
		return getColor()+"圆形";
	}
	public static void main(String[] args){
		Shape s1=new Triangle("黑色",3,4,5);
		Shape s2=new Circle("黄色", 3);
		System.out.println(s1.getType());
		System.out.println(s1.cal());
		System.out.println(s2.getType());
		System.out.println(s2.cal());
	}

	

}

抽象类的作用:抽象类是从多个具体的类中抽象出来的父类,为多个子类的通用模板,具有跟高层次的抽象,避免了子类设计的随意性。

接口

[修饰符]   interface 接口名 extends 父接口1,父接口2...

{

零个到多个常量定义

零个到多个抽象方法定义

零个到多个内部类、接口、枚举定义...

零个到多个私有方法、默认方法或类定义方法...

}    

  • 修饰符可以是public或者省略,如果省略了public访问控制符,则默认访问包权限访问控制符,只有在相同包结构下才可以访问该接口。
  • 接口名应与类名采用相同的命名规则。
  • 一个接口可以有多个直接父类接口,但接口只能继承接口,不能继承类。
  • 接口里的方法只能是抽象方法、类方法、默认方法和私有方法。
public interface Output {
	//接口里定义的成员变量只能是常量
	int Line=50;
	//接口里定义的普通方法只能是public抽象方法
	void out();
	void getData(String msg);
	//在接口中定义默认方法,需要使用default修饰
	default void test(){
		System.out.println("默认的test()方法");
	}
    //在接口中定义类方法,需要使用static修饰
	static String staticTest(){
		return "接口里的类方法";
		
	}
	  //定义私有方法
	 static void foo() {
		System.out.println("foo私有的方法");
	}
	//定义私有静态方法
	static void bar() {
		System.out.println("bar私有的静态方法");
	}
}

接口不能用于创建实例,但接口可以用于声明引用类型变量。当使用接口来声明引用类型变量时,这个引用类型变量必须引用到其实现类的对象。除此之外,接口的主要用途就是被实现类实现。接口用途如下:

  • 定义变量,也可用于进行强制类型转换
  • 调用接口中定义的常量
  • 被其他类实现

使用接口

  • 一个类实现某个接口时,该类将会获得接口中定义的常量(成员变量)、方法等
  • 一个类实现一个或多个接口之后,这个类必须完全实现这些接口里所定义的全部抽象方法(也就是重写这些抽象方法);否则该类将保留从父接口继承的抽象方法,该类也必须定义成抽象类。
public class Printer implements Output,Product{
    private String[] printData=new String[Line];
    //用于记录当前需打印的作业数
    private int dataNum=0;
   
	@Override
	public void out() {
		// TODO Auto-generated method stub
		//只要还有作业,就继续打印
		while(dataNum>0){
			System.out.println("打印机打印"+printData[0]);
			//把作业队列整体前移一位,并将剩下的作业数减1
			System.arraycopy(printData, 1, printData, 0, --dataNum);
		}
	}

	@Override
	public void getData(String msg) {
		// TODO Auto-generated method stub
		if(dataNum>=Line){
			System.out.println("输出队列已满,添加失败");
		}else{
			//把打印数据添加到队列里,已保存数据的数量+1
			printData[dataNum++]=msg;
		}
	}

	@Override
	public int getProduceTime() {
		// TODO Auto-generated method stub
		return 45;
	}
	public static void main(String[] args) {
		//创建一个Printer对象,当成Output使用
		Output o=new Printer();
		o.getData("123");
		o.getData("456");
		o.out();
		o.getData("777");
		o.getData("888");
		o.out();
		//调用Output接口中定义的默认方法
		o.print("enen..","oo..","aa..");
		o.test();
		//创建一个printer对象,当成Product使用
		Product p=new Printer();
		System.out.println(p.getProduceTime());
		//所有接口类型引用变量都可以直接赋值给Object类型的变量
		Object obj=p;
	}

}

接口和抽象类的区别

  • 接口里只能包含抽象方法、静态方法、默认方法和私有方法,不能为普通方法提供方法实现;抽象类可以完全包含普通方法。
  • 接口里只能定义静态常量,不能定义普通成员变量;抽象类里既可以定义普通成员变量,也可以定义静态常量。
  • 接口里不包含构造器;抽象类里可以包含构造器,抽象类里的构造器不是用于创建对象,而是让其子类调用这些构造器来完成属性抽象类的初始化操作
  • 接口里不能包含初始化块,但抽象类则可以包含初始化块
  • 一个类最多只能有一个直接父类,包括抽象类。但一个类可以直接实现多个接口,通过实现多个接口弥补JAVA单继承的不足。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值