JAVA基礎再回首(七)——final關鍵字、抽象類abstract、接口interface、權限修飾符、導包
沒有到不了的明天。
嬉皮笑臉面對人生的難。
相信自己,不然你什麼都做不了。
final關鍵字
- final關鍵字是最終的意思,可以修飾類,成員變量,成員方法。
- 修飾類,類不能被繼承
- 修飾變量,變量就變成了常量,只能被賦值一次
- 修飾方法,方法不能被重寫
我們可以寫一個Demo來驗證一下final關鍵字
class Fu {
public int num = 10;
public final int num2 = 20;
/*
public final void show() {
}
*/
}
class Zi extends Fu {
// Zi中的show()無法覆蓋Fu中的show()
public void show() {
num = 100;
System.out.println(num);
//無法爲最終變量num2分配值
//num2 = 200; //打開註釋會報錯
System.out.println(num2);
}
}
public class FinalDemo{
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
輸出結果:
100
20
那麼final在繼承中如何體現呢?
由於繼承中方法有一個現象:方法重寫。所以,父類的功能就會被子類覆蓋掉。有時候爲了不讓子類去覆蓋掉父類的功能,只能讓他用,所以,針對這種情況,java就提供了一個關鍵字:final。
class Fu {
public final void show() {
System.out.println("這裏是絕密資源,任何人都不能修改");
}
}
class Zi extends Fu {
// Zi中的show()無法覆蓋Fu中的show()
// public void show() {
// System.out.println("這是一堆垃圾");
// }
}
public class FinalDemo{
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
輸出結果:
肯定是父類中的輸出結果了。
抽象類(abstract)
概述:
動物不應該定義爲具體的東西,而且動物中的吃,睡等也不應該是具體的。
我們把一個不是具體的功能稱爲抽象的功能,而一個類中如果有抽象的功能,該類必須是抽象類。
- 抽象類特點
- 抽象類和抽象方法必須用abstract關鍵字修飾
- 格式
- abstract class 類名 {}
- public abstract void eat();
- 抽象類不一定有抽象方法,有抽象方法的類一定是抽象類
- 抽象類不能實例化
- 因爲它不是具體的。
- 那麼,抽象類如何實例化呢?
- 按照多態的方式,由具體的子類實例化。其實這也是多態的一種,抽象類多態。
- 抽象類的子類
- 如果不想重寫抽象方法,該子類是一個抽象類。
- 重寫所有的抽象方法,這個時候子類是一個具體的類。
- 抽象類和抽象方法必須用abstract關鍵字修飾
abstract class Animal {
//抽象方法
//public abstract void eat(){} //空方法體,這個會報錯。抽象方法不能有主體
public abstract void eat();
public Animal(){}
}
//子類是抽象類
abstract class Dog extends Animal {}
//子類是具體類,重寫抽象方法
class Cat extends Animal {
public void eat() {
System.out.println("貓吃魚");
}
}
輸出結果:貓吃魚
- 抽象類的成員特點:
- 成員變量:既可以是變量,也可以是常量。
- 構造方法:構造方法不能被實例化。所以構造方法的特點是:用於子類訪問父類數據的初始化。
- 抽象類的成員方法特性:
- 可以有抽象方法,強制要求子類做的事情。
- 也可以有非抽象方法,子類繼承的事情,提高代碼複用性。
abstract class Animal {
public int num = 10;
public final int num2 = 20;
public Animal() {}
public Animal(String name,int age){}
public abstract void show();
public void method() {
System.out.println("method");
}
}
class Dog extends Animal {
public void show() {
System.out.println("show Dog");
}
}
public class AbstractDemo {
public static void main(String[] args) {
//創建對象
Animal a = new Dog();
a.num = 100;
System.out.println(a.num);
//a.num2 = 200;
System.out.println(a.num2);
System.out.println("--------------");
a.show();
a.method();
}
}
輸出結果:
我們學習了抽象方法,但是讓我有兩個疑惑的問題,不知道你們是不是也同樣疑惑,我給大家解答一下。
一個類如果沒有抽象方法,可不可以定義爲抽象類?如果可以,有什麼意義?
答案肯定是可以的,意義就是爲了不讓創建對象。
abstract不能和哪些關鍵字共存?
private衝突、final衝突、static無意義
下面我們實例一個Demo
public class AbstractDemo {
public static void main(String[] args) {
Father.methods();
}
}
abstract class Father{
//public abstract void show();
//非法的修飾符組合: abstract和private
//private abstract void show();
//非法的修飾符組合 abstract和final
//final abstract void show();
//非法的修飾符組合abstract和static
//static abstract void show();
public static void methods() {
System.out.println("method");
}
}
class Son extends Father {
public void show() {}
}
接口(interface)
- 接口用關鍵字interface表示
- 格式:interface 接口名 {}
- 類實現接口用implements表示
- 格式:class 類名 implements 接口名 {}
- 接口不能實例化
- 那麼,接口如何實例化呢?
- 按照多態的方式,由具體的子類實例化。其實這也是多態的一種,接口多態(下一節講)。
- 接口的子類
- 可以是抽象類。但是意義不大。
- 可以是具體類。要重寫接口中的所有抽象方法。(推薦方案)
//定義動物培訓接口
interface AnimalTrain {
public abstract void jump();
}
//抽象類實現接口
abstract class Dog implements AnimalTrain {
}
//具體類實現接口
class Cat implements AnimalTrain {
public void jump() {
System.out.println("貓可以跳高了");
}
}
public class InterfaceDemo {
public static void main(String[] args) {
//AnimalTrain是抽象的; 無法實例化
//AnimalTrain at = new AnimalTrain();
//at.jump();
AnimalTrain at = new Cat();
at.jump();
}
}
輸出結果:貓可以跳高了
- 接口成員特點
- 成員變量;只能是常量,並且是靜態的。
- 默認修飾符:public static final
- 建議:自己手動給出。
- 構造方法:接口沒有構造方法。因爲接口主要是擴展功能的,而沒有具體存在
- 成員方法:只能是抽象方法。
- 默認修飾符:public abstract
- 建議:自己手動給出。
interface Inter {
public int num = 10;
public final int num2 = 20;
public static final int num3 = 30;
//錯誤: 需要<標識符>,接口沒有構造方法
//public Inter() {}
//接口方法不能帶有主體
//public void show() {}
//abstract void show(); //默認public
public void show(); //默認abstract
}
class InterImpl extends Object implements Inter {
public InterImpl() {
super();
}
@Override
public void show() {
}
}
public class InterfaceDemo {
public static void main(String[] args) {
//創建對象
Inter i = new InterImpl();
System.out.println(i.num);
System.out.println(i.num2);
//i.num = 100;
//i.num2 = 200;
//System.out.println(i.num); //無法爲最終變量num分配值
//System.out.println(i.num2);//無法爲最終變量num2分配值
System.out.println(Inter.num);
System.out.println(Inter.num2);
}
}
輸出結果:
10
20
10
20
類與類,類與接口以及接口與接口的關係
覺得他們的關係好複雜,快看暈了,沒關係,我們逐個學習
- 類與類:
- 繼承關係,只能單繼承,可以多層繼承。
- 類與接口:
- 實現關係,可以單實現,也可以多實現。
- 並且還可以在繼承一個類的同時實現多個接口。
- 接口與接口:
- 繼承關係,可以單繼承,也可以多繼承。
interface Father{
public abstract void show();
}
interface Mother {
public abstract void show2();
}
interface Sister extends Father,Mother {
}
class Son extends Object implements Father,Mother {
public void show() {
System.out.println("show son");
}
public void show2() {
System.out.println("show2 son");
}
}
public class InterfaceDemo {
public static void main(String[] args) {
//創建對象
Father f = new Son();
f.show();
//f.show2(); //報錯
Mother m = new Son();
//m.show(); //報錯
m.show2();
}
}
輸出結果:
show2 son
show son
上面我們學習了抽象類,又學習了接口。那麼他們之間有什麼區別呢?我們繼續開車…
抽象類和接口的區別
成員區別
- 抽象類:
- 成員變量:可以變量,也可以常量
- 構造方法:有
- 成員方法:可以抽象,也可以非抽象
- 接口:
- 成員變量:只可以常量
- 成員方法:只可以抽象
- 抽象類:
關係區別
- 類與類
- 繼承,單繼承
- 類與接口
- 實現,單實現,多實現
- 接口與接口
- 繼承,單繼承,多繼承
- 類與類
- 設計理念區別
- 抽象類
- 被繼承體現的是:”is a”的關係。
- 抽象類中定義的是該繼承體系的共性功能。
- 接口
- 被實現體現的是:”like a”的關係。
- 接口中定義的是該繼承體系的擴展功能。
- 抽象類
權限修飾符
- 修飾符:
- 權限修飾符:private,默認的,protected,public
- 狀態修飾符:static,final
- 抽象修飾符:abstract
- 類:
- 權限修飾符:默認修飾符,public
- 狀態修飾符:final
- 抽象修飾符:abstract
- 用的最多的就是:public
- 成員變量:
- 權限修飾符:private,默認的,protected,public
- 狀態修飾符:static,final
- 用的最多的就是:private
- 構造方法:
- 權限修飾符:private,默認的,protected,public
- 用的最多的就是:public
- 權限修飾符:private,默認的,protected,public
- 成員方法:
- 權限修飾符:private,默認的,protected,public
- 狀態修飾符:static,final
- 抽象修飾符:abstract
- 用的最多的就是:public
- 除此以外的組合規則:
- 成員變量:
- public static final
- 成員方法:
- public static
- public abstract
- public final
- 成員變量:
最後我們在學一個小知識點——>導包
導包
- 導包概述
- 不同包下的類之間的訪問,我們發現,每次使用不同包下的類的時候,都需要加包的全路徑。比較麻煩。這個時候,java就提供了導包的功能。
- 導包格式
- import 包名;
- 注意:
- 我們用那個報就導那個包。
那麼,package,import,class有沒有順序關係?
答案是肯定有關係。
package > import > class
Package:只能有一個
import:可以有多個
class:可以有多個,以後建議是一個
今天我們就學到這裏,明天我們來學習多態。
最後呢,歡迎有興趣的同學加我朋友的QQ羣:555974449
羣主呢,也就是我在第一篇博客我畢業了中給大家提到的劉某人程序員。
我們在羣裏等你!