Java 抽象类和接口,抽象类和接口基础,实现抽象类和接口

编译环境

  • windows 10
  • JDK 1.8
  • eclipse



前言

  上一篇文章中,粗略的了解了多态,也了解到了一小些关于抽象类和接口,所以决定写一篇详细一点的关于抽象类和接口的文章。



抽象类(Abstract class)

  一、基本概念

  抽象类不可以用于创建对象。抽象类可以包含抽象方法,这些方法将在具体的子类中实现。抽象类和抽象方法使用abstract关键字来创建。抽象类不能实例化对象,所以抽象类必须被继承才能够被使用。

  在抽象方法中,抽象方法只包含一个方法名,方法名后边直接跟一个分号,而不是花括号;抽象方法没有具体实现方法的方法体,具体的实现要靠子类的重写来实现。但是任何子类必须重写父类的抽象方法,或者声明自身为抽象类。不可以只定义一个抽象方法,继承父类的子类不重写该抽象方法。如果一个类包含抽象方法,那么该类必须是抽象类。


  二、抽象类的几点说明

  1、抽象方法不能包含在非抽象类中,在实现抽象类的子类中,必须实现所有的抽象方法,而且要注意的是抽象方法是非静态的。

  2、抽象类是不能使用new操作来初始化的,但是仍然可以有构造方法,这个构造方法在它的子类的构造方法中调用。

  3、包含抽象方法的类必须是抽象的,但是可以定义一个不含抽象方法的抽象类。

  4、子类可以覆盖父类的方法并将它定义为abstract。

  5、即使子类的父类是具体的,这个子类也可以是抽象的。


  三、代码实例

  1、定义合法的抽象类

/** 文件名 A.class */
public abstract class A {
    
} 

/** 文件名 A.class */
public abstract class A {
    public abstract void unfinished();
}

/** 文件名 xxx.class */
abstract class A {
    
}

/** 文件名 xxx.class */
abstract class A {
    abstract void unfinished();
}

/** 文件名 xxx.class */
abstract class A {
    public void unfinished(){
    }
}

/** 文件名 xxx.class */
abstract class A {
    protected void unfinished(){
    }
}

解释说明:

  如果使用到public来定义一个抽象类的话,那么文件名要和该类的名字是相同的。


  2、继承抽象类

/** 文件名 Debug.class */

public class Debug {
	/** Main method */
	public static void main(String[] args) {
		Children child = new Children();
		child.print(); // 调用子类重写方法
		child.test(); // 调用父类的方法
	}
}

/** 抽象类 */
abstract class Parent {
	/* 抽象方法 */
	abstract void print();

	/* 非抽象方法 */
	public void test() {
		System.out.println("Parent\'s method");
	}
}

/** 实现抽象类的子类 */
class Children extends Parent {
	/* 重写父类的抽象方法 */
	@Override
	public void print() {
		System.out.println("Hello World!");
	}
}

输出:

Hello World!
Parent's method

解释说明:

  父类定义为抽象类,然后通过子类的非抽象类来继承父类,实现了父类的抽象方法,但是父类的非抽象方法,在子类也是可以直接使用的。



接口(Interface)

  一、基本概念

  接口不是类,接口被看作是一种特殊的类。一个类通过继承接口的方式,从而来继承接口的抽象方法。接口跟抽象类很相似,**不能只定义一个方法,而实现接口的类不去重写接口的方法,除非实现接口的类是抽象类,否则该类要重写定义接口中的所有方法。**一个类可以实现多个接口,但是只能继承一个父类。接口使用关键字interface来声明。


  二、抽象类和接口

  1、抽象类中的方法可以有方法体,但是接口中的方法没有方法体。

  2、抽象类的成员变量可以是各种类型的,而接口中的变量只能是public static final类型的。

  3、接口中不能含有静态代码块以及静态方法,而抽象类是可以有静态代码块和静态方法的。(JDK 1.8 之后,接口里可以有静态方法和方法体了)

  4、一个类只能继承一个抽象类,而一个类却可以实现多个接口。

变量构造方法方法
抽象类无限制子类通过构造方法调用构造方法,抽象类不能用new操作符实例化无限制
接口所有的变量必须是public static final没有构造方法,接口不可以用new操作符实例化所有方法必须是公共的抽象实例方法

  三、接口特性

  1、接口中每一个方法也是隐式抽象的,接口中的方法也会被隐式的指定为public abstract。

  2、接口中可以含有变量,但是接口中的变量会被隐式的指定为public static final 变量。

  3、接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

  4、当类实现接口的时候,类要实现接口中所有的方法,否则类必须声明为抽象类。


  四、代码实例

  1、由于接口中所有的数据域都是public static final,而且所有方法都是public abstract,所以Java允许忽略这些修饰符。因此。下面的接口定义是等价的:

/** 文件名 A.class */

public interface A {
    /* 变量 */
	public static final int a = 0;
    
    /* 方法 */
    public abstract void method();
}

/** 上下两个接口的定义是等价的 */

public interface A {
    /* 变量 */
    int a = 0;
    
    /* 方法 */
    void method();
}

  2、接口的实现

/** 文件名 Debug.class */

public class Debug {
    /** Main method */
    public static void main(String[] args) {
        Pen pen = new Pen(); // 调用实现接口的类
		pen.yellow();		// 调用改类方法
    }
}

/** 接口 */
interface Color {

	/* 抽象方法 */
	void yellow();
}

/** 实现接口 */
class Pen implements Color {

    /* 实现抽象方法 */
	@Override
	public void yellow() {
		System.out.println("My pen color is yellow");
	}
}

输出:

My pen color is yellow

解释说明:

  接口通过关键字implements来实现。


  3、接口的多继承和实现多个接口

/** 文件名 Debug.class */

/** 接口1 */
interface Pen {

	/* 抽象方法 */
	void pen();
}

/** 接口2 */
interface Apple {

	/* 抽象方法 */
	void apple();
}

/** 接口3 */
interface All extends Pen, Apple {

	/* 抽象方法 */
	void pineapple();
}

/** 实现接口 */
class Song implements All {

	@Override
	public void pen() {
		System.out.println("I have a pen");
	}

	@Override
	public void apple() {
		System.out.println("I have an apple");
	}

	@Override
	public void pineapple() {
		System.out.println("I have a pineapple");
	}

	public void play() {
		this.pen();
		this.apple();
		this.pineapple();
		System.out.println();
	}
}

public class Debug {
	/** Main method */
	public static void main(String[] args) {
		Song song = new Song();
		song.play();
	}
}

/** 实现多个接口的方式
class Song implements Pen, Apple {
}
*/

输出:

I have a pen
I have an apple
I have a pineapple

解释说明:

  继承了多个接口之后,实现接口的类,要把接口中所有的抽象方法都重写。



总结

  Java中的接口是非常有用的,接口的灵活性要比抽象类要高。讲完抽象类和接口后,你是不是会有这样子一个疑问:既然抽象类和接口的实现都要在子类进行重写,那么为什么不直接把这些接口中的方法直接写在子类中呢?可以参考一下这个文章https://blog.csdn.net/weixin_41804194/article/details/79506045



参考

1、https://lingcoder.gitee.io/onjava8/#/sidebar

2、https://www.runoob.com/java/java-tutorial.html

3、https://blog.csdn.net/weixin_41804194/article/details/79506045

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值