Java中抽象類(lèi)和接口的使用及區(qū)別分析
一、 抽象類(lèi)
1、概念
在面向?qū)ο蟮母拍钪?,所有的?duì)象都是通過(guò)類(lèi)來(lái)描繪的,但是反過(guò)來(lái),并不是所有的類(lèi)都是用來(lái)描繪對(duì)象的,如果一個(gè)類(lèi)中沒(méi)有包含足夠的信息來(lái)描繪一個(gè)具體的對(duì)象,這樣的類(lèi)就是抽象類(lèi)。
舉個(gè)例子:

1.這里Animal類(lèi)是動(dòng)物類(lèi),每個(gè)動(dòng)物都有自己的叫法,但這里Animal不是一個(gè)具體的動(dòng)物,里面的bark()方法無(wú)法具體實(shí)現(xiàn)。
2.Dog是狗類(lèi)屬于動(dòng)物,與Animal類(lèi)是繼承關(guān)系,狗是一種具體的動(dòng)物,所以里面的bark()方法可以被具體實(shí)現(xiàn)。
3.Cat是貓類(lèi)屬于動(dòng)物,與Animal類(lèi)是繼承關(guān)系,貓是一種具體的動(dòng)物,所以里面的bark()方法可以被具體實(shí)現(xiàn)。
4.因此,這里的Animal類(lèi)可以設(shè)計(jì)為抽象類(lèi)。
2、抽象類(lèi)語(yǔ)法
在Java中,一個(gè)類(lèi)如果被 abstract 修飾稱(chēng)為抽象類(lèi),抽象類(lèi)中被 abstract 修飾的方法稱(chēng)為抽象方法,抽象方法不用給出具體的實(shí)現(xiàn)體。抽象類(lèi)也是類(lèi),內(nèi)部可以包含普通方法和屬性,甚至構(gòu)造方法。
舉個(gè)例子:
//抽象類(lèi)
public abstract class Animal {
public int age;
abstract public void eat(); //抽象方法
public Animal(int a) {
this.age = a;
}
}3、抽象類(lèi)的特性
3.1抽象類(lèi)不能直接實(shí)例化對(duì)象
Animal抽象類(lèi)
public abstract class Animal {
public int age;
abstract public void eat(); //抽象方法
public Animal(int a) {
this.age = a;
}
}Dog類(lèi)繼承Animal抽象類(lèi)
public class Dog extends Animal{
public void eat() {
System.out.println("汪汪叫...");
}
public void sleep(){
System.out.println("小狗正在睡覺(jué)....");
}
public Dog(int age){
super(age);
}
}Test測(cè)試類(lèi)
public class Test {
public static void main(String[] args) {
Animal animal = new Animal(); //error
}
}
這里實(shí)例化Animal抽象類(lèi),編譯器報(bào)錯(cuò)。
3.2抽象方法不能是private
public abstract class Animal {
public int age;
abstract private void bark(); //error,抽象方法不能是私有的
abstract public void eat(); //抽象方法
}
3.3抽象方法不能被final和static修飾,因?yàn)槌橄蠓椒ㄒ蛔宇?lèi)重寫(xiě)
public abstract class Animal {
public int age;
abstract final public void eat(); //error
abstract public static void bark();//error
}3.4抽象類(lèi)必須被繼承,并且繼承后子類(lèi)要重寫(xiě)父類(lèi)中的抽象方法,否則子類(lèi)也是抽象類(lèi),必須要使用 abstract 修飾
Animal抽象類(lèi)
public abstract class Animal {
public int age;
abstract public void eat(); //抽象方法
public Animal(int a) {
this.age = a;
}
}Dog類(lèi)繼承Animal抽象類(lèi)
public class Dog extends Animal{
public void eat() {
System.out.println("汪汪叫...");
}
public void sleep(){
System.out.println("小狗正在睡覺(jué)....");
}
public Dog(int age){
super(age);
}
}這里Dog類(lèi)繼承了Animal抽象類(lèi),并且Dog類(lèi)重寫(xiě)了Animal抽象類(lèi)中的eat()抽象方法。
3.5抽象類(lèi)中不一定包含抽象方法,但是有抽象方法的類(lèi)一定是抽象類(lèi)
public abstract class Animal {
public int age;
public Animal(int a) {
this.age = a;
}
}
這里Animal是抽象類(lèi),但里面沒(méi)有包含抽象方法,是可以正常編譯的。
public class Dog extends Animal{ //error
abstract public void sleep(){
System.out.println("小狗正在睡覺(jué)....");
}
public void eat() {
System.out.println("汪汪叫...");
}
public Dog(int age){
super(age);
}
}這里Dog類(lèi)不是抽象類(lèi),如果里面寫(xiě)了抽象方法,則編譯器會(huì)報(bào)錯(cuò)。
3.6抽象類(lèi)中可以有構(gòu)造方法,供子類(lèi)創(chuàng)建對(duì)象時(shí),初始化父類(lèi)的成員變量
這里上面的代碼中已經(jīng)體現(xiàn)到了。
4、 抽象類(lèi)的作用
使用抽象類(lèi)的場(chǎng)景就如上面的代碼, 實(shí)際工作不應(yīng)該由父類(lèi)完成, 而應(yīng)由子類(lèi)完成. 那么此時(shí)如果不小心誤用成父類(lèi)了, 使用普通類(lèi)編譯器是不會(huì)報(bào)錯(cuò)的. 但是父類(lèi)是抽象類(lèi)就會(huì)在實(shí)例化的時(shí)候提示錯(cuò)誤, 讓我們盡早發(fā)現(xiàn)問(wèn)題。使用抽象類(lèi)相當(dāng)于多了一重編譯器的校驗(yàn)。
二、接口
1、概念
在Java中,接口可以看成是:多個(gè)類(lèi)的公共規(guī)范,是一種引用數(shù)據(jù)類(lèi)型。
2、接口的語(yǔ)法和使用
1.接口的定義格式與定義類(lèi)的格式基本相同,將class關(guān)鍵字換成 interface 關(guān)鍵字,就定義了一個(gè)接口。
public interface 接口名稱(chēng){
//抽象方法
void method();
}
2.接口不能直接使用,必須要有一個(gè)"實(shí)現(xiàn)類(lèi)"來(lái)"實(shí)現(xiàn)"該接口,實(shí)現(xiàn)接口中的所有抽象方法。
public class 類(lèi)名 implements 接口名稱(chēng){
}3.注意事項(xiàng)
子類(lèi)和父類(lèi)之間是extends 繼承關(guān)系,類(lèi)與接口之間是 implements 實(shí)現(xiàn)關(guān)系。
3、接口的特性
1.接口中的成員變量默認(rèn)是public static final修飾的。
2.接口中的抽象方法,默認(rèn)都是public abstract修飾的。
舉個(gè)例子:Ishape接口
public interface IShape {
int c = 20; //成員變量默認(rèn)是public static final 修飾的
void draw(); //默認(rèn)是abstract修飾的
}
3.如果接口當(dāng)中的方法被default或者static修飾,那么可以有具體實(shí)現(xiàn)。
public interface IShape {
default void test(){
System.out.println("default.....");
}
static void test1(){
System.out.println("static.....");
}
4.接口不可以進(jìn)行實(shí)例化。
5.類(lèi)和接口之間可以使用關(guān)鍵字implements實(shí)現(xiàn)接口。
舉個(gè)例子:
IShape接口
public interface IShape {
void draw(); //默認(rèn)是abstract修飾的
}
Cycle類(lèi)
public class Cycle implements IShape{
@Override
public void draw() {
System.out.println("畫(huà)一個(gè)圓圈.....");//必須實(shí)現(xiàn)接口當(dāng)中的抽象方法
}
}
6.一個(gè)接口對(duì)應(yīng)一個(gè)字節(jié)碼文件。
7.重寫(xiě)接口中方法時(shí),不能使用默認(rèn)的訪(fǎng)問(wèn)權(quán)限。(子類(lèi)的重寫(xiě)方法權(quán)限要大于等于父類(lèi))
8.接口中不能有靜態(tài)代碼塊和構(gòu)造方法。
9.如果類(lèi)沒(méi)有實(shí)現(xiàn)接口中的所有的抽象方法,則類(lèi)必須設(shè)置為抽象類(lèi)。
4、一個(gè)類(lèi)實(shí)現(xiàn)多個(gè)接口
接下來(lái)我會(huì)通過(guò)代碼來(lái)闡述一個(gè)類(lèi)實(shí)現(xiàn)多個(gè)接口
舉個(gè)例子
Animal抽象類(lèi)
public abstract class Animal {
public String name;
public int age;
public Animal(String name,int age){
this.name = name;
this.age = age;
}
public abstract void eat();
}
IRunning 接口
public interface IRunning {
void run();
}
ISwimming 接口
public interface ISwimming {
void swim();
}
Frog類(lèi)繼承Animal抽象類(lèi)并實(shí)現(xiàn)了IRunning,ISwimming兩個(gè)接口
public class Frog extends Animal implements IRunning,ISwimming{
public Frog(String name, int age) {
super(name, age);
}
public void sleep(){
System.out.println(this.name+"正在睡覺(jué)...");
}
@Override
public void eat() {
System.out.println(this.name+"正在吃蟲(chóng)子...");
}
@Override
public void run() {
System.out.println(this.name+"正在跑步..");
}
@Override
public void swim() {
System.out.println(this.name+"會(huì)游泳.....");
}
}Test測(cè)試類(lèi)
public class Test {
public static void swimming(ISwimming iSwimming){
iSwimming.swim();
}
public static void running(IRunning iRunning){
iRunning.run();
}
public static void main(String[] args) {
swimming(new Frog("小蛙",1));
running((new Frog("小綠",2)));
}打印結(jié)果

上述代碼:一個(gè)Frog類(lèi)實(shí)現(xiàn)了IRunning,ISwimming兩個(gè)接口,從而闡述了一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口。
三、抽象類(lèi)和接口的區(qū)別
抽象類(lèi)中可以包含普通方法和字段,這樣的包含普通方法和字段可以被子類(lèi)直接使用,不用重寫(xiě)。而接口中不能包含普通方法,子類(lèi)必須重寫(xiě)所有的抽象方法。
到此這篇關(guān)于Java中抽象類(lèi)和接口的使用及區(qū)別分析的文章就介紹到這了,更多相關(guān)java抽象類(lèi)和接口使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java 實(shí)現(xiàn)增量同步和自定義同步的操作
這篇文章主要介紹了java 實(shí)現(xiàn)增量同步和自定義同步的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01
Spring Boot 基于注解的 Redis 緩存使用詳解
本篇文章主要介紹了Spring Boot 基于注解的 Redis 緩存使用詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05
Freemaker Replace函數(shù)的正則表達(dá)式運(yùn)用
這篇文章主要介紹了Freemaker Replace函數(shù)的正則表達(dá)式運(yùn)用 的相關(guān)資料,需要的朋友可以參考下2015-12-12
Java中l(wèi)ambda表達(dá)式實(shí)現(xiàn)aop切面功能
本文主要介紹了Java中l(wèi)ambda表達(dá)式實(shí)現(xiàn)aop切面功能,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
SpringCache緩存抽象之CacheManager與自定義鍵生成方式
本文將深入探討Spring Cache的核心組件CacheManager及自定義鍵生成策略,幫助開(kāi)發(fā)者掌握緩存配置與優(yōu)化技巧,從而構(gòu)建高效可靠的緩存系統(tǒng),希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04
Java中Integer的parseInt和valueOf的區(qū)別詳解
這篇文章主要介紹了Java中Integer的parseInt和valueOf的區(qū)別詳解,nteger.parseInt(s)是把字符串解析成int基本類(lèi)型,Integer.valueOf(s)是把字符串解析成Integer對(duì)象類(lèi)型,其實(shí)int就是Integer解包裝,Integer就是int的包裝,需要的朋友可以參考下2023-11-11

