文檔版本 | 開發(fā)工具 | 測(cè)試平臺(tái) | 工程名字 | 日期 | 作者 | 備注 |
---|---|---|---|---|---|---|
V1.0 | 2016.02.29 | lutianfei | none |
[TOC]
final 關(guān)鍵字
final關(guān)鍵字,可以修飾
類
苛吱,成員變量
酪术,成員方法
。-
特點(diǎn):
- 修飾的
類
,類不能被繼承 - 修飾的
變量
绘雁,變量就變成了常量橡疼,只能被<font color = red>賦值一次</font> - 修飾的
方法
,方法不能被重寫
- 修飾的
final關(guān)鍵字面試題
-
Eg1: final修飾局部變量
- 在方法內(nèi)部庐舟,該變量不可以被改變
- 在方法聲明上欣除,分為
基本類型
和引用類型
作為參數(shù)的情況- 基本類型,是值不能被改變
- 引用類型挪略,是地址值不能被改變历帚,但是該對(duì)象堆內(nèi)存的值可以改變。
-
Eg2: final修飾變量的初始化時(shí)機(jī)
- 在對(duì)象構(gòu)造完畢前即可
class Student {
int age = 10;
}
class FinalTest {
public static void main(String[] args) {
//局部變量是基本數(shù)據(jù)類型
int x = 10;
x = 100;
System.out.println(x);
final int y = 10;
//無法為最終變量y分配值
//y = 100;
System.out.println(y);
System.out.println("--------------");
//局部變量是引用數(shù)據(jù)類型
Student s = new Student();
System.out.println(s.age);
s.age = 100;
System.out.println(s.age);
System.out.println("--------------");
final Student ss = new Student();
System.out.println(ss.age);
ss.age = 100;
System.out.println(ss.age);
//重新分配內(nèi)存空間
//無法為最終變量ss分配值
ss = new Student();
}
}
多態(tài)
多態(tài)概述
- 某一個(gè)事物杠娱,在不同時(shí)刻表現(xiàn)出來的不同狀態(tài)挽牢。
- 舉例:
- 貓可以是貓的類型。貓 m = new 貓();
- 同時(shí)貓也是動(dòng)物的一種摊求,也可以把貓稱為動(dòng)物禽拔。
- 動(dòng)物 d = new 貓();
- 再舉一個(gè)例子:水在不同時(shí)刻的狀態(tài)
- 舉例:
- 多態(tài)前提和體現(xiàn)
- 有繼承關(guān)系
- 有方法重寫
- 有父類引用指向子類對(duì)象
- Fu f = new Zi();
多態(tài)的分類:
- 具體類多態(tài):
- class Fu{}
- class Zi extends Fu{}
- Fu f = new Zi();
- 抽象類多態(tài):
- abstract class Fu{}
- class Zi extends Fu{}
- Fu f = new Zi();
- 接口多態(tài):
- interface Fu{}
- class Zi implements Fu{}
- Fu f = new Zi();
多態(tài)中的成員訪問特點(diǎn):
A:
成員變量
:編譯看左邊,運(yùn)行看左邊室叉。B:
構(gòu)造方法
:創(chuàng)建子類對(duì)象的時(shí)候睹栖,訪問父類的構(gòu)造方法,對(duì)父類的數(shù)據(jù)進(jìn)行初始化太惠。C:
成員方法
: <font color = red>編譯看左邊磨淌,運(yùn)行看右邊</font>疲憋。由于成員方法存在方法重寫凿渊,所以它運(yùn)行看右邊。-
D:
靜態(tài)方法
:編譯看左邊缚柳,運(yùn)行看左邊埃脏。- (靜態(tài)和類相關(guān),算不上重寫秋忙,所以彩掐,訪問還是左邊的)
/*
多態(tài):同一個(gè)對(duì)象(事物),在不同時(shí)刻體現(xiàn)出來的不同狀態(tài)灰追。
舉例:
貓是貓堵幽,貓是動(dòng)物。
水(液體弹澎,固體朴下,氣態(tài))。
多態(tài)的前提:
A:要有繼承關(guān)系苦蒿。
B:要有方法重寫殴胧。
其實(shí)沒有也是可以的,但是如果沒有這個(gè)就沒有意義。
動(dòng)物 d = new 貓();
d.show();
動(dòng)物 d = new 狗();
d.show();
C:要有父類引用指向子類對(duì)象团滥。
父 f = new 子();
*/
class Fu {
public int num = 100;
public void show() {
System.out.println("show Fu");
}
public static void function() {
System.out.println("function Fu");
}
}
class Zi extends Fu {
public int num = 1000;
public int num2 = 200;
public void show() {
System.out.println("show Zi");
}
public void method() {
System.out.println("method zi");
}
public static void function() {
System.out.println("function Zi");
}
}
class DuoTaiDemo {
public static void main(String[] args) {
//要有父類引用指向子類對(duì)象竿屹。
//父 f = new 子();
Fu f = new Zi();
System.out.println(f.num);
//找不到符號(hào)
//System.out.println(f.num2);
f.show();
//找不到符號(hào)
//f.method();
f.function();
}
}
/*
* 運(yùn)行結(jié)果:
100
show Zi
function Fu
*/
多態(tài)的優(yōu)缺點(diǎn)
-
多態(tài)的好處
- 提高了程序的維護(hù)性(由繼承保證)
- 提高了程序的擴(kuò)展性(由多態(tài)保證)
-
多態(tài)的弊端
- 父類不能訪問子類特有功能
-
如何才能訪問子類的特有功能呢?
- 創(chuàng)建子類對(duì)象,調(diào)用方法即可灸姊。(然而很多時(shí)候不合理拱燃,且太占內(nèi)存)
-
向下轉(zhuǎn)型
:把父類的引用強(qiáng)制轉(zhuǎn)換為子類的引用。- Zi z = (Zi)f; //要求該f必須是能夠轉(zhuǎn)換為Zi的
現(xiàn)象: 子可以當(dāng)做父使用厨钻,父不能當(dāng)作子使用扼雏。
多態(tài)中的轉(zhuǎn)型問題
- 向上轉(zhuǎn)型
- 從子到父
- 父類引用指向子類對(duì)象
- 向下轉(zhuǎn)型
- 從父到子
- 父類引用轉(zhuǎn)為子類對(duì)象
- 孔子裝爹案例
//多態(tài)的問題理解:
class 孔子爹 {
public int age = 40;
public void teach() {
System.out.println("講解JavaSE");
}
}
class 孔子 extends 孔子爹 {
public int age = 20;
public void teach() {
System.out.println("講解論語");
}
public void playGame() {
System.out.println("英雄聯(lián)盟");
}
}
//Java培訓(xùn)特別火,很多人來請(qǐng)孔子爹去講課,這一天孔子爹被請(qǐng)走了
//但是還有人來請(qǐng)夯膀,就适洌孔子在家,價(jià)格還挺高诱建『眩孔子一想,我是不是可以考慮去呢?
//然后就穿上爹的衣服俺猿,帶上爹的眼睛茎匠,粘上爹的胡子。就開始裝爹
//向上轉(zhuǎn)型
孔子爹 k爹 = new 孔子();
//到人家那里去了
System.out.println(k爹.age); //40
k爹.teach(); //講解論語
//k爹.playGame(); //這是兒子才能做的,一做就報(bào)錯(cuò)押袍!
//講完了诵冒,下班回家了
//脫下爹的裝備,換上自己的裝備
//向下轉(zhuǎn)型
孔子 k = (孔子) k爹;
System.out.println(k.age); //20
k.teach(); //講解論語
k.playGame(); //英雄聯(lián)盟
-
多態(tài)中的對(duì)象變化內(nèi)存圖
- 多態(tài)練習(xí):貓狗案例
class Animal {
public void eat(){
System.out.println("吃飯");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("狗吃肉");
}
public void lookDoor() {
System.out.println("狗看門");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("貓吃魚");
}
public void playGame() {
System.out.println("貓捉迷藏");
}
}
class DuoTaiTest {
public static void main(String[] args) {
//定義為狗
Animal a = new Dog();
a.eat();
System.out.println("--------------");
//還原成狗
Dog d = (Dog)a;
d.eat();
d.lookDoor();
System.out.println("--------------");
//變成貓
a = new Cat();
a.eat();
System.out.println("--------------");
//還原成貓
Cat c = (Cat)a;
c.eat();
c.playGame();
System.out.println("--------------");
}
}
- 不同地方飲食文化不同的案例
class Person {
public void eat() {
System.out.println("吃飯");
}
}
class SouthPerson extends Person {
public void eat() {
System.out.println("炒菜,吃米飯");
}
public void jingShang() {
System.out.println("經(jīng)商");
}
}
class NorthPerson extends Person {
public void eat() {
System.out.println("燉菜,吃饅頭");
}
public void yanJiu() {
System.out.println("研究");
}
}
class DuoTaiTest2 {
public static void main(String[] args) {
//測(cè)試
//南方人
Person p = new SouthPerson();
p.eat();
System.out.println("-------------");
SouthPerson sp = (SouthPerson)p;
sp.eat();
sp.jingShang();
System.out.println("-------------");
//北方人
p = new NorthPerson();
p.eat();
System.out.println("-------------");
NorthPerson np = (NorthPerson)p;
np.eat();
np.yanJiu();
}
}
/*
運(yùn)行結(jié)果:
炒菜,吃米飯
-------------
炒菜,吃米飯
經(jīng)商
-------------
燉菜,吃饅頭
-------------
燉菜,吃饅頭
研究
*/
多態(tài)中繼承練習(xí)
-
繼承的時(shí)候:
- 子類中有和父類中一樣的方法谊惭,叫
重寫
汽馋。 - 子類中沒有父親中出現(xiàn)過的方法,方法就被
繼承
過來了圈盔。
- 子類中有和父類中一樣的方法谊惭,叫
Eg:(<font color = red>不太理解</font>)
/*
多態(tài)的成員訪問特點(diǎn):
方法:編譯看左邊豹芯,運(yùn)行看右邊。
繼承的時(shí)候:
子類中有和父類中一樣的方法驱敲,叫重寫铁蹈。
子類中沒有父親中出現(xiàn)過的方法,方法就被繼承過來了众眨。
*/
class A {
public void show() {
show2();
}
public void show2() {
System.out.println("我");
}
}
class B extends A {
/*
public void show() {
show2();
}
*/
public void show2() {
System.out.println("愛");
}
}
class C extends B {
public void show() {
super.show();
}
public void show2() {
System.out.println("你");
}
}
public class DuoTaiTest4 {
public static void main(String[] args) {
A a = new B();
a.show();
B b = new C();
b.show();
}
}
// 運(yùn)行結(jié)果:
//愛
//你
抽象類
抽象類概述
- 動(dòng)物本身并不是一個(gè)具體的事物握牧,而是一個(gè)抽象的事物。只有真正的貓娩梨,狗才是具體的動(dòng)物沿腰。同理,我們也可以推想姚建,不同的動(dòng)物吃的東西應(yīng)該是不一樣的矫俺,所以,我們不應(yīng)該在動(dòng)物類中給出具體體現(xiàn),而是應(yīng)該給出一個(gè)聲明即可厘托。在Java中友雳,一個(gè)沒有
方法體
(連<font color = red>大括號(hào)</font>也沒有)的方法應(yīng)該定義為抽象方法
,而類中如果有抽象方法
铅匹,該類必須定義為抽象類
押赊。
抽象類特點(diǎn)
-
抽象類
和抽象方法
必須用abstract
關(guān)鍵字修飾- 格式
- abstract class 類名 {}
- public abstract void eat();
- 格式
-
抽象類
不一定有抽象方法
,有抽象方法
的類一定是抽象類
- 抽象類不能實(shí)例化(抽象類如何實(shí)例化呢?)
- 按照多態(tài)的方式包斑,由具體的子類實(shí)例化流礁。其實(shí)這也是多態(tài)的一種,抽象類多態(tài)罗丰。
- 抽象類有
構(gòu)造方法
神帅,其作用是為了用于子類訪問父類數(shù)據(jù)的初始化。
- 抽象類的
子類
- 要么是抽象類
- 要么重寫抽象類中的所有
抽象方法
//abstract class Animal //抽象類的聲明格式
abstract class Animal {
//抽象方法
//public abstract void eat(){} //空方法體,這個(gè)會(huì)報(bào)錯(cuò)萌抵。抽象方法不能有主體
public abstract void eat();
public Animal(){}
}
//子類是抽象類
abstract class Dog extends Animal {}
//子類是具體類找御,重寫抽象方法
class Cat extends Animal {
public void eat() {
System.out.println("貓吃魚");
}
}
class AbstractDemo {
public static void main(String[] args) {
//創(chuàng)建對(duì)象
//Animal是抽象的; 無法實(shí)例化
//Animal a = new Animal();
//通過多態(tài)的方式
Animal a = new Cat();
a.eat();
}
}
抽象類的成員特點(diǎn)
- 成員變量
- 可以是變量
- 也可以是常量
- 構(gòu)造方法
- 有構(gòu)造方法,但是不能實(shí)例化
- 那么绍填,構(gòu)造方法的作用是什么呢?
- 用于子類訪問父類數(shù)據(jù)的初始化
- 成員方法
- 可以有抽象方法 作用:限定子類必須完成某些動(dòng)作
- 也可以有非抽象方法 提高代碼復(fù)用性
- 抽象定義類練習(xí):
//定義抽象的動(dòng)物類
abstract class Animal {
//姓名
private String name;
//年齡
private int age;
public Animal() {}
public Animal(String name,int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//定義一個(gè)抽象方法
public abstract void eat();
}
//定義具體的狗類
class Dog extends Animal {
public Dog() {}
public Dog(String name,int age) {
super(name,age); //重要知識(shí)點(diǎn)vΑ!讨永!
}
public void eat() {
System.out.println("狗吃肉");
}
}
//定義具體的貓類
class Cat extends Animal {
public Cat() {}
public Cat(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("貓吃魚");
}
}
//測(cè)試類
class AbstractTest {
public static void main(String[] args) {
//測(cè)試狗類
//具體類用法
//方式1:
Dog d = new Dog();
d.setName("旺財(cái)");
d.setAge(3);
System.out.println(d.getName()+"---"+d.getAge());
d.eat();
//方式2:
Dog d2 = new Dog("旺財(cái)",3);
System.out.println(d2.getName()+"---"+d2.getAge());
d2.eat();
System.out.println("---------------------------");
Animal a = new Dog();
a.setName("旺財(cái)");
a.setAge(3);
System.out.println(a.getName()+"---"+a.getAge());
a.eat();
Animal a2 = new Dog("旺財(cái)",3);
System.out.println(a2.getName()+"---"+a2.getAge());
a2.eat();
//練習(xí):測(cè)試貓類
}
}
- 抽象教師類練習(xí):
//定義抽象的老師類
abstract class Teacher {
//姓名
private String name;
//年齡
private int age;
public Teacher() {}
public Teacher(String name,int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//抽象方法
public abstract void teach();
}
//基礎(chǔ)班老師類
class BasicTeacher extends Teacher {
public BasicTeacher(){}
public BasicTeacher(String name,int age) {
super(name,age);
}
public void teach() {
System.out.println("基礎(chǔ)班老師講解JavaSE");
}
}
//就業(yè)班老師類
class WorkTeacher extends Teacher {
public WorkTeacher(){}
public WorkTeacher(String name,int age) {
super(name,age);
}
public void teach() {
System.out.println("就業(yè)班老師講解JavaEE");
}
}
class AbstractTest2 {
public static void main(String[] args) {
//具體的類測(cè)試滔驶,自己玩
//測(cè)試(多態(tài))
//基礎(chǔ)班老師
Teacher t = new BasicTeacher();
t.setName("劉意");
t.setAge(30);
System.out.println(t.getName()+"---"+t.getAge());
t.teach();
System.out.println("--------------");
t = new BasicTeacher("劉意",30);
System.out.println(t.getName()+"---"+t.getAge());
t.teach();
System.out.println("--------------");
//就業(yè)班老師
t = new WorkTeacher();
t.setName("林青霞");
t.setAge(27);
System.out.println(t.getName()+"---"+t.getAge());
t.teach();
System.out.println("--------------");
t = new WorkTeacher("林青霞",27);
System.out.println(t.getName()+"---"+t.getAge());
t.teach();
}
}
抽象類的幾個(gè)小問題
- 一個(gè)類如果沒有抽象方法,可以定義為抽象類?如果可以卿闹,有什么意義?
- 可以
- 禁止創(chuàng)建對(duì)象
-
abstract
不能和哪些關(guān)鍵字共存-
private
沖突 -
final
沖突 -
static
無意義(通過類名直接訪問沒有內(nèi)容的方法體)
-
接口
接口概述
- 狗一般就是看門揭糕,貓一般就是作為寵物。但是比原,現(xiàn)在有很多的馴養(yǎng)員或者是馴獸師插佛,可以訓(xùn)練出:貓鉆火圈杠巡,狗跳高量窘,狗做計(jì)算等。而這些額外的動(dòng)作氢拥,并不是所有貓或者狗一開始就具備的蚌铜,這應(yīng)該屬于經(jīng)過特殊的培訓(xùn)訓(xùn)練出來的。所以嫩海,這些額外的動(dòng)作定義到動(dòng)物類中就不合適冬殃,也不適合直接定義到貓或者狗中,因?yàn)橹挥胁糠重埞肪邆溥@些功能叁怪。
所以审葬,為了體現(xiàn)事物功能的擴(kuò)展性,Java中就提供了接口
來定義這些額外功能,并不給出具體實(shí)現(xiàn)涣觉,將來哪些貓狗需要被培訓(xùn)痴荐,只需要這部分貓狗把這些額外功能實(shí)現(xiàn)即可。
接口特點(diǎn)
-
接口用關(guān)鍵字
interface
表示- 格式:interface 接口名 {}
-
類實(shí)現(xiàn)接口用
implements
表示- 格式:class 類名 implements 接口名 {}
-
接口不能實(shí)例化(接口如何實(shí)例化呢?)
- 按照多態(tài)的方式官册,由具體的子類實(shí)例化生兆。其實(shí)這也是多態(tài)的一種,接口多態(tài)膝宁。
-
接口的實(shí)現(xiàn)類(子類):
-
抽象類
:實(shí)現(xiàn)接口鸦难,但意義不大 -
具體類
:重寫接口中的所有抽象方法
-
-
補(bǔ)充:多態(tài)的三種形式
- 具體類多態(tài)(幾乎沒有)
- 抽象類多態(tài)(常用)
- 接口類多態(tài)(最常用 )
接口成員特點(diǎn)
-
成員變量
- 只能是
常量
- 默認(rèn)修飾符 public static final
- 只能是
-
構(gòu)造方法
- 沒有,因?yàn)榻涌谥饕菙U(kuò)展功能的员淫,而沒有具體存在合蔽。
- 所有的類都默認(rèn)繼承自一個(gè)類:Object。(類Object 是類層次結(jié)構(gòu)的根類介返。每個(gè)類都使用Object作為超類)
-
成員方法
- 只能是抽象方法
- 默認(rèn)修飾符 public abstract
類與類,類與接口以及接口與接口的關(guān)系
- 類與類
- 繼承關(guān)系辈末,只能單繼承,但是可以多層繼承
- 類與接口
-
實(shí)現(xiàn)關(guān)系映皆,
- 可以單實(shí)現(xiàn)挤聘,也可以<font color = red>多實(shí)現(xiàn)</font>。
- 還可以在繼承一個(gè)類的同時(shí)實(shí)現(xiàn)多個(gè)接口捅彻。
-
實(shí)現(xiàn)關(guān)系映皆,
- 接口與接口
- 繼承關(guān)系组去,可以單繼承,也可以<font color = red>多繼承</font>
抽象類和接口的區(qū)別
- 成員區(qū)別
- 抽象類
- 成員變量:變量,常量;
- 構(gòu)造方法:可以有
- 成員方法:可以是抽象方法步淹,也可以是非抽象方法;
- 接口
- 成員變量:只可以是常量;
- 構(gòu)造方法:沒有
- 成員方法:只能是抽象方法
- 抽象類
- 關(guān)系區(qū)別
- 類與類 繼承从隆,單繼承
- 類與接口 實(shí)現(xiàn),單實(shí)現(xiàn)缭裆,多實(shí)現(xiàn)
- 接口與接口 繼承键闺,單繼承,多繼承
- 設(shè)計(jì)理念區(qū)別
- 抽象類 被繼承體現(xiàn)的是:”is a”的關(guān)系澈驼。抽象類中定義的是該繼承體系的共性功能
- 接口 被實(shí)現(xiàn)體現(xiàn)的是:”like a”的關(guān)系辛燥。接口中定義的是該繼承體系的擴(kuò)展功能
- 跳高貓練習(xí):
/*
貓狗案例,加入跳高的額外功能
分析:從具體到抽象
貓:
姓名,年齡
吃飯,睡覺
狗:
姓名,年齡
吃飯缝其,睡覺
由于有共性功能挎塌,所以,我們抽取出一個(gè)父類:
動(dòng)物:
姓名,年齡
吃飯();
睡覺(){}
貓:繼承自動(dòng)物
狗:繼承自動(dòng)物
跳高的額外功能是一個(gè)新的擴(kuò)展功能内边,所以我們要定義一個(gè)接口
接口:
跳高
部分貓:實(shí)現(xiàn)跳高
部分狗:實(shí)現(xiàn)跳高
實(shí)現(xiàn)榴都;
從抽象到具體
使用:
使用具體類
*/
//定義跳高接口
interface Jumpping {
//跳高功能
public abstract void jump();
}
//定義抽象類
abstract class Animal {
//姓名
private String name;
//年齡
private int age;
public Animal() {}
public Animal(String name,int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//吃飯();
public abstract void eat();
//睡覺(){}
public void sleep() {
System.out.println("睡覺覺了");
}
}
//具體貓類
class Cat extends Animal {
public Cat(){}
public Cat(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("貓吃魚");
}
}
//具體狗類
class Dog extends Animal {
public Dog(){}
public Dog(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("狗吃肉");
}
}
//有跳高功能的貓
class JumpCat extends Cat implements Jumpping {
public JumpCat() {}
public JumpCat(String name,int age) {
super(name,age);
}
public void jump() {
System.out.println("跳高貓");
}
}
//有跳高功能的狗
class JumpDog extends Dog implements Jumpping {
public JumpDog() {}
public JumpDog(String name,int age) {
super(name,age);
}
public void jump() {
System.out.println("跳高狗");
}
}
class InterfaceTest {
public static void main(String[] args) {
//定義跳高貓并測(cè)試
JumpCat jc = new JumpCat();
jc.setName("哆啦A夢(mèng)");
jc.setAge(3);
System.out.println(jc.getName()+"---"+jc.getAge());
jc.eat();
jc.sleep();
jc.jump();
System.out.println("-----------------");
JumpCat jc2 = new JumpCat("加菲貓",2);
System.out.println(jc2.getName()+"---"+jc2.getAge());
jc2.eat();
jc2.sleep();
jc2.jump();
//定義跳高狗并進(jìn)行測(cè)試的事情自己完成。
}
}
-
運(yùn)行結(jié)果