JavaSE基礎知識學習—–抽象類和介面

讀書遛狗遠方發表於2019-02-18

abstract關鍵字

abstract:抽象的,可以用來修飾類和方法,當abstract修飾類的時候,該類就叫抽象類,修飾方法時,就叫抽象方法。

什麼叫抽象類

在java中,因為繼承,使得類越來越具體化,類的設計使得父類越來越通用,在類的設計裡應該保證父類和子類能夠共享特徵,有時候就把父類設計的非常抽象,讓它沒有具體的例項。這樣的類就叫抽象類,例如人可以說話,但是不同的人可能說的話不一樣,所以讓說話的內容由子類自己決定。

1.抽象類不可以被例項化,例項化應該是它的子類來完成

public class TestAbstract {
	public static void main(String[] args) {
		Person person = new Person();
		person.eat();
	}
}
class Person{
	public void eat(){
		System.out.println("人吃飯");
	}
	public void walk(){
		System.out.println("人走路");
	}
}
class Teacher extends Person{
	public void eat(){
		System.out.println("教師吃飯");
	}
	public void walk(){
		System.out.println("教師走路");
	}
}
class Student extends Person{
	public void eat(){
		System.out.println("學生吃飯");
	}
	public void walk(){
		System.out.println("學生走路");
	}
}
複製程式碼

從上述程式碼可以看出,如果Person類沒有被abstract修飾,在main方法裡是可以被例項化的,如果我們加上了abstract關鍵字修飾,那麼Person person = new Person();就會被報錯。

2.抽象類是類的一種,也有構造器

很神奇的是,抽象類不能被例項化,但是卻可以存在構造器,

abstract class Person{
	String name;
	int age;
	public void eat(){
		System.out.println("人吃飯");
	}
	public void walk(){
		System.out.println("人走路");
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Person() {
		super();
	}
}
複製程式碼

3.抽象方法所在的類一定是抽象類

abstract class Person{
	public abstract void eat();
	public abstract void walk();
}
複製程式碼

abstract修飾方法

abstract修飾的方法也叫抽象方法,關於抽象方法需要說明以下幾點:
1.抽象方法的格式,沒有方法體,就是不包括{},例如public abstract void eat();
2.抽象方法值保留方法的功能,具體的實現過程由繼承他的子類來實現,
3.如果子類繼承了抽象類沒有全部實現父類抽象方法,則表明子類還是一個抽象類,也必須用abstract修飾類,
4.如果子類繼承了抽象類,並且全部重寫了父類抽象方法,則該子類就可以被例項化。

4.抽象類中可以沒有抽象方法

abstract class Person{
	public void eat(){
		System.out.println("人吃飯");
	}
	public void walk(){
		System.out.println("人走路");
	}
}
複製程式碼

5.抽象方法必須由子類來重寫

abstract class Person{
	public abstract void eat();
	public abstract void walk();
}
class Teacher extends Person{
	public void eat(){
		System.out.println("教師吃飯");
	}
	public void walk(){
		System.out.println("教師走路");
	}
}
複製程式碼

從上述程式碼也能得出,子類繼承一個抽象類,要麼全部實現父類的抽象方法,要麼本身還是一個抽象類。

6.子類中的抽象方法不能和父類的抽象方法同名

7.abstract不能與final修飾同一個類,原因很簡單,final修飾的類不能被繼承,

8.abstract不能與private,static,final,native並列修飾同一個方法

這三點大家都可以試試,道理也很簡單。下面一個例子說明抽象類的相關知識;

public class TestAbstract {
	public static void main(String[] args) {
		Person p1 = new Teacher();
		p1.eat();
		Person p2 = new Student();
		p2.eat();
		Teacher t1 = new Teacher();
		t1.eat();
		Student s1 = new Student();
		s1.eat();
	}
}
abstract class Person{
	public  abstract void eat();
	public abstract void walk();
}
class Teacher extends Person{
	public void eat(){
		System.out.println("教師吃飯");
	}
	public void walk(){
		System.out.println("教師走路");
	}
}
class Student extends Person{
	public void eat(){
		System.out.println("學生吃飯");
	}
	public void walk(){
		System.out.println("學生走路");
	}
}
複製程式碼

結果為:

教師吃飯
學生吃飯
教師吃飯
學生吃飯
複製程式碼

模板方法設計模式

抽象類體現的就是一種模板設計模式,抽象類作為多個子類通用的模板,子類在抽象類的基礎上進行擴充套件,這種模式解決的就是一部分功能不確定,就把不確定的功能部分暴露出去,讓子類自己去實現。

案例

public class TestTemplate {
	public static void main(String[] args) {
		new subTemplate().spendTime();
	}
}
abstract class Template{
	public abstract void testAbstract();
	public void spendTime(){
		long start = System.currentTimeMillis();
		this.testAbstract();
		long end = System.currentTimeMillis();
		System.out.println("執行testAbstract方法花費的時間為"+(end-start));
	}
}
class subTemplate extends Template{

	@Override
	public void testAbstract() {//求10000以內的素數
		boolean flag = false;
		for(int i = 2; i <= 10000;i++){
			for(int j = 2;j <=Math.sqrt(i);j++){
				if(i % j == 0){
					flag = true;
					break;
				}
			}if(!flag){
				System.out.println(i);
			}
			flag = false;
		}
	}
	
}
複製程式碼

介面

介面是一種比抽象類還抽象的東西,它不是類,不能被例項化,只能例項化他的子類。使用關鍵字interface,實現介面的類就必須實現介面中的所有方法,這個在javaee中的三層架構中會經常使用。在使用介面的過程中需要注意一下幾點:
1.一個類可以實現多個介面,也可以繼承其他介面。
2.介面中只能有常量和抽象方法。
3.介面的許可權只能是public,你可以手動宣告為其他,編譯就會報錯。
4.介面中定義的“成員變數”,也加不可變的常量,因為會自動加上public static final,可以通過介面名.常量名進行訪問。
5.介面主要用於定義規範,接觸耦合關係

public interface TestInterface {
 public void show();
 public void updateEmployee();
}
複製程式碼

這就是一個介面,只是說介面沒有太多說的,主要是介面有什麼用,java為什麼會提供這麼一個東西,介面在JAVAEE中使用很多,例如Mybatis基於介面的mapper開發。JavaEE三層模式開發都會大量使用介面。下面主要學習介面的應用。

介面的多型性

public class Test {
	public static void main(String[] args) {
		Duck duck = new Duck();
		Test.test1(duck);
		Test.test2(duck);
		Test.test3(duck);
	}
	
	public static void test1(Swim s){
		s.swim();
	}
	public static void test2(Runner r){
		r.runner();
	}
	public static void test3(Fly f){
		f.fly();
	}

}
interface Swim{
	public abstract void swim();
}
interface Runner{
	public abstract void runner();
}
interface Fly{
	public abstract void fly();
}
class Duck implements Swim,Fly,Runner{

	@Override
	public void runner() {
		System.out.println("鴨子跑起來了");
	}

	@Override
	public void fly() {
		System.out.println("鴨子飛起來了");
	}

	@Override
	public void swim() {
		System.out.println("鴨子游起來了");
	}
	
}
複製程式碼

繼承的多型是子類重寫父類方法,父類引用指向不同的子類例項,就會呼叫對應子類的方法,從而執行不同的響應,
介面的多型是實現類實現多個介面,方法引數列表裡可以帶介面的引用引數,方法的具體可以通過介面引用呼叫介面裡的抽象方法,呼叫該方法時傳入介面實現類,實際執行的是實現類中的方法。這是相同的例項,不同的介面體現的多型性。

介面應用-工廠方法的設計模式

定義一個用於建立物件的介面,讓子類決定例項化哪一個類。簡單來講就是暴露介面給使用者,根據使用者傳入的引數返回特定的例項物件的一種模式。
例如:一個生產汽車的工廠,有很多分廠,生產火車的,生產轎車的,生產貨車的,使用者不知道有這些分廠,使用者只知道有一個工廠可以生產車,這個工廠是虛擬的,使用者在介面傳入編號,由工廠返回使用者指定的車例項。
案例如下:

public class TestFactory {
	public static void main(String[] args) {
		IWorkFactory factory = new StudentWorkFactory();
		factory.getWork().doWork();
		
		IWorkFactory factory2 = new TeacherWorkFactory();
		factory2.getWork().doWork();
	}

}
interface IWorkFactory{
	Work getWork();
}
class StudentWorkFactory implements IWorkFactory{

	@Override
	public Work getWork() {
		return new StudentWork();
	}
	
}
class TeacherWorkFactory implements IWorkFactory{

	@Override
	public Work getWork() {
		return new TeacherWork();
	}
	
}
interface Work{
	void doWork();
}
class StudentWork implements Work{

	@Override
	public void doWork() {
		System.out.println("學生寫作業");
	}
	
}
class TeacherWork implements Work{

	@Override
	public void doWork() {
		System.out.println("教師批改作業");
	}
	
}
複製程式碼

抽象類和介面的區別

總的來說:抽象類和介面都不能被例項化,但是都可以定義抽象類和介面的引用。
1.抽象類可以有抽象方法,也可以有方法的具體實現,介面中不能。
2.抽象類中的成員修飾可以為private,預設,protected,public但是介面中只能為public。
3.抽象類可以定義成員變數,但是介面中其實都是不可變的常量。
抽象類如下:

abstract class TestAbstractDemo{
	String name;
	abstract void test1();
	void test2(){
		System.out.println("我是具體方法");
	}
}
複製程式碼

介面如下:

interface TestInterfaceDemo{
	 String name="Hello";
	 abstract void test1();
	 abstract void test2();
 }
複製程式碼

總結:

程式設計中,什麼時候使用介面,什麼時候使用抽象類,這是一個架構的難點,只有對問題充分了解才能選擇合適的設計方法,抽象類在java中表示的是一種繼承關係,一個子類只存在一個父類,但是卻可以實現多個介面。

相關文章