這輩子沒辦法做太多事情,所以每一件都要做到精彩絕倫蚊荣。 --------史蒂夫.喬布斯
關鍵字(final)
(1)是最終的意思,可以修飾類啦扬,方法,變量。
(2)特點:
A:它修飾的類快毛,不能被繼承格嗅。
B:它修飾的方法,不能被重寫唠帝。
C:它修飾的變量屯掖,是一個常量。
(3)面試相關:
A:局部變量
a:基本類型 值不能發(fā)生改變
b:引用類型 地址值不能發(fā)生改變没隘,但是對象的內(nèi)容是可以改變的
B:初始化時機
a:只能初始化一次懂扼。
b:常見的給值
定義的時候。(推薦)
構(gòu)造方法中右蒲。
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);
}
}
class FinalDemo {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
/*
面試題:final修飾局部變量的問題
基本類型:基本類型的值不能發(fā)生改變。
引用類型:引用類型的地址值不能發(fā)生改變赶熟,但是瑰妄,該對象的堆內(nèi)存的值是可以改變的。
*/
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)
(1)同一個對象在不同時刻體現(xiàn)出來的不同狀態(tài)映砖。
(2)多態(tài)的前提:
A:有繼承或者實現(xiàn)關系间坐。
B:有方法重寫。
C:有父類或者父接口引用指向子類對象邑退。
多態(tài)的分類:
a:具體類多態(tài)
class Fu {}
class Zi extends Fu {}
Fu f = new Zi();
b:抽象類多態(tài)
abstract class Fu {}
class Zi extends Fu {}
Fu f = new Zi();
c:接口多態(tài)
interface Fu {}
class Zi implements Fu {}
Fu f = new Zi();
(3)多態(tài)中的成員訪問特點
A:成員變量
編譯看左邊竹宋,運行看左邊
B:構(gòu)造方法
子類的構(gòu)造都會默認訪問父類構(gòu)造
C:成員方法
編譯看左邊,運行看右邊
D:靜態(tài)方法
編譯看左邊地技,運行看左邊
為什么?
因為成員方法有重寫蜈七。
(4)多態(tài)的好處:
A:提高代碼的維護性(繼承體現(xiàn))
B:提高代碼的擴展性(多態(tài)體現(xiàn))
(5)多態(tài)的弊端:
父不能使用子的特有功能。
現(xiàn)象:
子可以當作父使用莫矗,父不能當作子使用飒硅。
(6)多態(tài)中的轉(zhuǎn)型
A:向上轉(zhuǎn)型
從子到父
B:向下轉(zhuǎn)型
從父到子
(7)孔子裝爹的案例幫助大家理解多態(tài)
(8)多態(tài)的練習
A:貓狗案例
B:老師和學生案例
/*
看程序?qū)懡Y(jié)果:先判斷有沒有問題,如果沒有作谚,寫出結(jié)果
多態(tài)的成員訪問特點:
方法:編譯看左邊三娩,運行看右邊。
繼承的時候:
子類中有和父類中一樣的方法妹懒,叫重寫雀监。
子類中沒有父親中出現(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();
}
}
多態(tài)的問題理解
多態(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培訓特別火,很多人來請孔子爹去講課会前,這一天孔子爹被請走了
//但是還有人來請,就实グ螅孔子在家回官,價格還挺高÷С龋孔子一想歉提,我是不是可以考慮去呢?
//然后就穿上爹的衣服笛坦,帶上爹的眼睛,粘上爹的胡子苔巨。就開始裝爹
//向上轉(zhuǎn)型
孔子爹 k爹 = new 孔子();
//到人家那里去了
System.out.println(k爹.age); //40
k爹.teach(); //講解論語
//k爹.playGame(); //這是兒子才能做的
//講完了版扩,下班回家了
//脫下爹的裝備,換上自己的裝備
//向下轉(zhuǎn)型
孔子 k = (孔子) k爹;
System.out.println(k.age); //20
k.teach(); //講解論語
k.playGame(); //英雄聯(lián)盟
抽象類
(1)把多個共性的東西提取到一個類中侄泽,這是繼承的做法礁芦。
但是呢,這多個共性的東西悼尾,在有些時候柿扣,方法聲明一樣,但是方法體闺魏。
也就是說未状,方法聲明一樣,但是每個具體的對象在具體實現(xiàn)的時候內(nèi)容不一樣析桥。
所以司草,我們在定義這些共性的方法的時候,就不能給出具體的方法體泡仗。
而一個沒有具體的方法體的方法是抽象的方法埋虹。
在一個類中如果有抽象方法,該類必須定義為抽象類娩怎。
(2)抽象類的特點
A:抽象類和抽象方法必須用關鍵字abstract修飾
B:抽象類中不一定有抽象方法,但是有抽象方法的類一定是抽象類
C:抽象類不能實例化
D:抽象類的子類
a:是一個抽象類搔课。
b:是一個具體類。這個類必須重寫抽象類中的所有抽象方法峦树。
(3)抽象類的成員特點:
A:成員變量
有變量辣辫,有常量
B:構(gòu)造方法
有構(gòu)造方法
C:成員方法
有抽象,有非抽象
(4)抽象類的練習
A:貓狗案例練習
B:老師案例練習
C:學生案例練習
D:員工案例練習
(5)抽象類的幾個小問題
A:抽象類有構(gòu)造方法魁巩,不能實例化急灭,那么構(gòu)造方法有什么用?
用于子類訪問父類數(shù)據(jù)的初始化
B:一個類如果沒有抽象方法,卻定義為了抽象類,有什么用?
為了不讓創(chuàng)建對象
C:abstract不能和哪些關鍵字共存
a:final 沖突
b:private 沖突
c:static 無意義
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("貓吃魚");
}
}
class AbstractDemo {
public static void main(String[] args) {
//創(chuàng)建對象
//Animal是抽象的; 無法實例化
//Animal a = new Animal();
//通過多態(tài)的方式
Animal a = new Cat();
a.eat();
}
}
/*
假如我們在開發(fā)一個系統(tǒng)時需要對員工類進行設計,員工包含3個屬性:姓名肾扰、工號以及工資畴嘶。
經(jīng)理也是員工,除了含有員工的屬性外集晚,另為還有一個獎金屬性窗悯。
請使用繼承的思想設計出員工類和經(jīng)理類。要求類中提供必要的方法進行屬性訪問偷拔。
分析:
普通員工類
成員變量:姓名蒋院、工號以及工資亏钩。
成員方法:工作
經(jīng)理類:
成員變量:姓名、工號以及工資欺旧,獎金屬性
成員方法:工作
實現(xiàn):
員工類:
普通員工類:
經(jīng)理類:
*/
//定義員工類
abstract class Employee {
//姓名姑丑、工號以及工資
private String name;
private String id;
private int salary;
public Employee() {}
public Employee(String name,String id,int salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
//工作
public abstract void work();
}
//普通員工類
class Programmer extends Employee {
public Programmer(){}
public Programmer(String name,String id,int salary) {
super(name,id,salary);
}
public void work() {
System.out.println("按照需求寫代碼");
}
}
//經(jīng)理類
class Manager extends Employee {
//獎金
private int money; //bonus 獎金
public Manager(){}
public Manager(String name,String id,int salary,int money) {
super(name,id,salary);
this.money = money;
}
public void work() {
System.out.println("跟客戶談需求");
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
class AbstractTest4 {
public static void main(String[] args) {
//測試普通員工
Employee emp = new Programmer();
emp.setName("財源");
emp.setId("czbk001");
emp.setSalary(18000);
System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());
emp.work();
System.out.println("-------------");
emp = new Programmer("財源","czbk001",18000);
System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());
emp.work();
System.out.println("-------------");
//由于子類有特有的內(nèi)容,所以我們用子類來測試
Manager m = new Manager();
m.setName("小源同學");
m.setId("czbk002");
m.setSalary(8000);
m.setMoney(2000);
System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());
m.work();
System.out.println("-------------");
//通過構(gòu)造方法賦值
m = new Manager("小源同學","czbk002",8000,2000);
System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());
m.work();
}
}
接口
(1)回顧貓狗案例辞友,它們僅僅提供一些基本功能栅哀。
比如:貓鉆火圈,狗跳高等功能称龙,不是動物本身就具備的留拾,
是在后面的培養(yǎng)中訓練出來的,這種額外的功能茵瀑,java提供了接口表示间驮。
(2)接口的特點:
A:接口用關鍵字interface修飾
interface 接口名 {}
B:類實現(xiàn)接口用implements修飾
class 類名 implements 接口名 {}
C:接口不能實例化
D:接口的實現(xiàn)類
a:是一個抽象類。
b:是一個具體類马昨,這個類必須重寫接口中的所有抽象方法。\
由此可見:
A:具體類多態(tài)(幾乎沒有)
B:抽象類多態(tài)(常用)
C:接口多態(tài)(最常用)
(3)接口的成員特點:
A:成員變量
只能是常量
默認修飾符:public static final
B:構(gòu)造方法
沒有構(gòu)造方法
C:成員方法
只能是抽象的
默認修飾符:public abstract
(4)類與類,類與接口,接口與接口
A:類與類
繼承關系扛施,只能單繼承鸿捧,可以多層繼承
B:類與接口
實現(xiàn)關系,可以單實現(xiàn)疙渣,也可以多實現(xiàn)匙奴。
還可以在繼承一個類的同時,實現(xiàn)多個接口
C:接口與接口
繼承關系妄荔,可以單繼承泼菌,也可以多繼承
(5)抽象類和接口的區(qū)別:
A:成員區(qū)別
抽象類:
成員變量:可以變量,也可以常量
構(gòu)造方法:有
成員方法:可以抽象啦租,也可以非抽象
接口:
成員變量:只可以常量
成員方法:只可以抽象
B:關系區(qū)別
類與類
繼承哗伯,單繼承
類與接口
實現(xiàn),單實現(xiàn)篷角,多實現(xiàn)
接口與接口
繼承焊刹,單繼承,多繼承
C:設計理念區(qū)別
抽象類 被繼承體現(xiàn)的是:”is a”的關系恳蹲。抽象類中定義的是該繼承體系的共性功能虐块。
接口 被實現(xiàn)體現(xiàn)的是:”like a”的關系。接口中定義的是該繼承體系的擴展功能嘉蕾。
//定義動物培訓接口
interface AnimalTrain {
public abstract void jump();
}
//抽象類實現(xiàn)接口
abstract class Dog implements AnimalTrain {
}
//具體類實現(xiàn)接口
class Cat implements AnimalTrain {
public void jump() {
System.out.println("貓可以跳高了");
}
}
class InterfaceDemo {
public static void main(String[] args) {
//AnimalTrain是抽象的; 無法實例化
//AnimalTrain at = new AnimalTrain();
//at.jump();
AnimalTrain at = new Cat();
at.jump();
}
}
/*
老師和學生案例,加入抽煙的額外功能
分析:從具體到抽象
老師:姓名贺奠,年齡,吃飯错忱,睡覺
學生:姓名儡率,年齡挂据,吃飯,睡覺
由于有共性功能喉悴,我們提取出一個父類棱貌,人類。
人類:
姓名箕肃,年齡
吃飯();
睡覺(){}
抽煙的額外功能不是人或者老師婚脱,或者學生一開始就應該具備的,所以勺像,我們把它定義為接口
抽煙接口障贸。
部分老師抽煙:實現(xiàn)抽煙接口
部分學生抽煙:實現(xiàn)抽煙接口
實現(xiàn):從抽象到具體
使用:具體
*/
//定義抽煙接口
interface Smoking {
//抽煙的抽象方法
public abstract void smoke();
}
//定義抽象人類
abstract class Person {
//姓名
private String name;
//年齡
private int age;
public Person() {}
public Person(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 Teacher extends Person {
public Teacher() {}
public Teacher(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("吃大白菜");
}
}
//具體學生類
class Student extends Person {
public Student() {}
public Student(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("吃紅燒肉");
}
}
//抽煙的老師
class SmokingTeacher extends Teacher implements Smoking {
public SmokingTeacher() {}
public SmokingTeacher(String name,int age) {
super(name,age);
}
public void smoke() {
System.out.println("抽煙的老師");
}
}
//抽煙的學生
class SmokingStudent extends Student implements Smoking {
public SmokingStudent() {}
public SmokingStudent(String name,int age) {
super(name,age);
}
public void smoke() {
System.out.println("抽煙的學生");
}
}
class InterfaceTest2 {
public static void main(String[] args) {
//測試學生
SmokingStudent ss = new SmokingStudent();
ss.setName("林青霞");
ss.setAge(27);
System.out.println(ss.getName()+"---"+ss.getAge());
ss.eat();
ss.sleep();
ss.smoke();
System.out.println("-------------------");
SmokingStudent ss2 = new SmokingStudent("小源同學",20);
System.out.println(ss2.getName()+"---"+ss2.getAge());
ss2.eat();
ss2.sleep();
ss2.smoke();
}
}