final
final:最終的意思,可以修飾類,成員方法,成員變量
特點:
final可以修飾類,該類不能被繼承。
final可以修飾方法,該方法不能被重寫。
final可以修飾變量,該變量不能被重新賦值,這個變量就是常量。
常量:
字面值常量
"hello",10,true
自定義常量
final int x = 10;
final修飾局部變量的問題
基本類型:基本類型的值不能發生改變
引用類型:引用類型的地址值不能發生改變,但是,該對象的堆內存的值是可以改變的。
final修飾變量的初始化時機
被final修飾的變量只能賦值一次。
在構造方法完畢前。(非靜態的常量)
多態
多態:同一個對象(事物),在不同時刻體現出來的不同狀態。
舉例:
貓是貓,貓是動物。
水(液體,固體,氣態)
多態的前提:
要有繼承關係。
要有方法重寫。
要有父類引用指向子類對象。
父 f = new 子();
多態中的成員訪問特點:
成員變量
編譯看左邊,運行看左邊(即只能訪問父類中的成員變量)
構造方法
創建子類對象的時候,訪問父類的構造方法,對父類的數據進行初始化。
成員方法
編譯看左邊,運行看右邊。(編譯訪問父類,運行先訪問子類因爲方法重寫把父類方法覆蓋掉)
靜態方法
編譯看左
邊,運行看左邊(靜態和類相關,算不上重寫,所以訪問還是父類)
由於成員方法存在方法重寫,所以它運行看子類。
多態的好處
提高了代碼的維護性(繼承保證)
提高了代碼的擴展性(由多態保證)
class Animal1{
public Animal1() {
}
public void eat() {
System.out.println("吃飯");
}
public void sleep() {
System.out.println("睡覺");
}
}
class Cat1 extends Animal1{
public Cat1() {
}
public void eat() {
System.out.println("貓吃魚");
}
public void sleep() {
System.out.println("貓趴着睡覺");
}
}
class Dog1 extends Animal1{
public Dog1() {
}
public void eat() {
System.out.println("狗吃肉");
}
public void sleep() {
System.out.println("狗站着睡");
}
}
class Animal1Tool{
private Animal1Tool() {
}
public static void useAnimal1(Animal1 a) {
a.eat();
a.sleep();
}
}
public class AnimalTest {
public static void main(String[] args) {
Animal1 c = new Cat1();
Animal1 c1 = new Cat1();
Animal1 c2 = new Cat1();
Animal1Tool.useAnimal1(c);
Animal1Tool.useAnimal1(c1);
Animal1Tool.useAnimal1(c2);
System.out.println("-----------------");
Dog1 d = new Dog1();
Dog1 d1 = new Dog1();
Dog1 d2 = new Dog1();
Animal1Tool.useAnimal1(d);
Animal1Tool.useAnimal1(d1);
Animal1Tool.useAnimal1(d2);
}
}
-----------------------------------------------------------------
結果:
貓吃魚
貓趴着睡覺
貓吃魚
貓趴着睡覺
貓吃魚
貓趴着睡覺
-----------------
狗吃肉
狗站着睡
狗吃肉
狗站着睡
狗吃肉
狗站着睡
多態的弊端:
不能使用子類的特有功能。
解決方法:
創建子類對象調用方法即可。(可以,但是很多時候不合理,且佔內存)
把父類的引用強制轉換爲子類的引用。(向下轉型)
對象間的轉型問題:
向上轉型:(從子到父,父類引用指向子類對象)
Fu f = new Zi();
向下轉型:(從父到子,父類引用轉爲子類對象)
Zi z = (Zi) f; (要求該 f 必須時能夠轉換爲Zi的。)
class Animal2{
public void eat() {
System.out.println("吃飯");
}
}
class Cat2 extends Animal2 {
public void eat() {
System.out.println("貓吃魚");
}
public void playGame() {
System.out.println("貓玩捉迷藏");
}
}
class Dog2 extends Animal2{
public void eat() {
System.out.println("狗吃肉");
}
public void LookDoor() {
System.out.println("狗看門");
}
}
public class DuoTaiCatDog {
public static void main(String[] args) {
Animal2 a = new Cat2();
a.eat();
System.out.println("--------");
Cat2 c = (Cat2)a;
c.eat();
c.playGame();
System.out.println("---------");
a = new Dog2();
a.eat();
System.out.println("--------");
Dog2 d =(Dog2)a;
d.eat();
d.LookDoor();
}
}
---------------------------------------------------------------
結果:
貓吃魚
--------
貓吃魚
貓玩捉迷藏
---------
狗吃肉
--------
狗吃肉
狗看門
抽象類的概述:
動物不應該定義爲具體的東西,而且動物中的吃,睡等也不應該是具體的。我們把一個不是具體的功能稱爲抽象的功能,而一個類中如果有抽象的功能,該類必須是抽象類。
抽象類的特點:
抽象類和抽象方法必須用abstract關鍵字修飾
格式:
abstract class 類名{}
public abstract void eat(); (抽象方法不能有方法體)
抽象類中不一定有抽象方法,但是有抽象方法的類必須定義爲抽象類。
抽象類不能實例化,因爲它不是具體的。不能創建對象。
抽象類有構造方法,但是不能實例化,構造方法是用於子類訪問父類數據的初始化
抽象的子類
如果不重寫抽象方法,該子類是一個抽象類。
重寫所有的抽象方法,這時候子類是一個具體的類。
抽象類的實例化是靠具體的子類實現的。多態的方法。
抽象類的成員特點:
成員變量:既可以是變量,也可以是常量。
構造方法:用於子類訪問父類數據的初始化。
成員方法:既可以是抽象的,也可以是非抽象的。
抽象類成員方法特性:
抽象方法 強制要求子類做的事情。
非抽象方法 子類繼承的事情,提高代碼複用性。
//抽象類
abstract class Animall{
//姓名
private String name;
//年齡
private int age;
//無參構造
public Animall() {
}
//帶參構造
public Animall(String name,int age) {
this.name=name;
this.age=age;
}
//抽象方法
public abstract void eat();
//getXxx()/setXxx()
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;
}
}
class Catt extends Animall{
//無參構造
public Catt() {
}
//帶參構造
public Catt(String name,int age) {
super(name,age);
}
//重寫方法
public void eat() {
System.out.println("貓吃魚");
}
}
class Dogg extends Animall{
//無參構造
public Dogg() {
}
//帶參構造
public Dogg(String name,int ags) {
super(name,ags);
}
//重寫方法
public void eat() {
System.out.println("狗吃肉");
}
}
public class AbstractTest {
public static void main(String[] args) {
//方式一
Catt c = new Catt();
c.setName("花花");
c.setAge(2);
c.eat();
System.out.println(c.getName()+"---"+c.getAge());
//方式二
Catt c2 = new Catt("花花",2);
c2.eat();
System.out.println(c2.getName()+"---"+c2.getAge());
System.out.println("-----------------");
//方式三
Animall a = new Dogg(); //多態
a.setName("旺財");
a.setAge(3);
a.eat();
System.out.println(a.getName()+"---"+a.getAge());
//方式四
Animall a2 = new Dogg("旺財",3);
a2.eat();
System.out.println(a2.getName()+"---"+a2.getAge());
}
}
----------------------------------------------------------------------------------------
結果:
貓吃魚
花花---2
貓吃魚
花花---2
-----------------
狗吃肉
旺財---3
狗吃肉
旺財---3
//抽象員工類
abstract class Employ{
//姓名
private String name;
//員工號
private String id;
//薪資
private int salary;
//無參構造
public Employ() {
}
//帶參構造
public Employ(String name,String id,int salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
//getXxx()/setXxx()
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 personnel extends Employ{
//無參構造
public personnel() {
}
//帶參構造
public personnel(String name,String id,int salary) {
super(name,id,salary);
}
//方法重寫
public void work() {
System.out.println("按照需求寫代碼");
}
}
//經理類
class manager extends Employ{
//獎金
private int bonus;
//無參構造
public manager() {
}
//帶參構造
public manager(String name,String id,int salary,int bonus) {
super(name,id,salary);
this.bonus = bonus;
}
//getXxx()/setXxx
public int getBonus() {
return bonus;
}
public void setBonus(int bonus) {
this.bonus = bonus;
}
//方法重寫
public void work() {
System.out.println("與客戶談需求");
}
}
public class EmployeeTest {
public static void main(String[] args) {
//多態向上轉型
Employ e = new personnel();
e.setName("小強");
e.setId("sd0001");
e.setSalary(15000);
e.work();
System.out.println(e.getName()+"---"+e.getId()+"---"+e.getSalary());
System.out.println("-----------");
e = new manager("小明","sd0010",25000,10000);
//多態向下轉型
manager m = (manager)e;
m.work();
System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getBonus());
}
}
-----------------------------------------------------------------------------------------
結果:
按照需求寫代碼
小強---sd0001---15000
-----------
與客戶談需求
小明---sd0010---25000---10000
一個類如果沒有抽象方法,定義爲爲抽象類的意義是不讓創建對象。
abstrace 不能和哪些關鍵子共存
private 衝突 (方法重寫衝突)
final 衝突 (方法重寫衝突)
static 無意義 (抽象方法無方法體,訪問無意義)
接口:
接口的特點:
接口用關鍵字interface表示
interface 接口名 { }
類實現接口用implements表示
class 類名 implements 接口名 { }
接口按照多態的方式實例化
接口的子類
可以是抽象類,但是意義不大。
可以是具體類。要重寫接口中的所有抽象方法。
由此可見
具體類多態(幾乎沒有)
抽象類多態(常用)
接口多態(最常用)
接口成員特點
成員變量:只能是常量,並且是靜態的。
默認修飾符:public static final 建議:自己給出
構造方法:接口沒有構造方法;因爲接口主要是擴展功能,而沒有具體存在
成員方法:只能是抽象方法。
默認修飾費用: public abstract
所有的類都默認繼承自一個類:Object。
類 Object 是類層次結構的跟類。每個類都使用 Object 作爲超類。
類與類:
繼承關係,只能單繼承,可以多層繼承。
類與接口:
實現關係,可以單實現,也可以多實現。
並且還可以在繼承一個類的同時實現多個接口。
接口與接口:
繼承關係,可以單繼承,也可以多繼承。
抽象類和接口的區別:
成員區別:
抽象類:
成員變量:可以變量,也可以常量
構造方法:有
成員方法:可以抽象,也可以非抽象
接口:
成員變量:只可以常量
成員方法:只可以抽象
關係區別:
類與類
繼承,單繼承
類與接口
實現,單繼承,多繼承
接口與接口
繼承,單繼承,多繼承
設計理念區別
抽象類 被繼承體現的是:“is a”的關係。抽象類中定義的是該繼承體系的共性功能。
接口 被實現體現的是:“like a”的關係。接口中定義的是該繼承體系的擴展功能。
interface Jumpping{
public abstract void jump();
}
abstract class Anmial{
//姓名
private String name;
//年齡
private int age;
//無參構造
public Anmial() {
}
//帶參構造
public Anmial(String name,int age) {
this.name=name;
this.age=age;
}
//getXxx()/setXxx()
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 Anmial {
//無參構造
public Cat() {
}
//帶參構造
public Cat(String name,int age) {
super(name,age);
}
//重寫方法
public void eat() {
System.out.println("貓吃魚");
}
}
class Dog extends Anmial{
//無參構造
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("跳高狗");
}
}
public class JumpDogCat {
public static void main(String[] args) {
JumpCat c = new JumpCat();
c.setName("Tom");
c.setAge(4);
System.out.println(c.getName()+"---"+c.getAge());
c.eat();
c.sleep();
c.jump();
System.out.println("---------");
JumpDog d = new JumpDog("旺財",5);
System.out.println(d.getName()+"---"+d.getAge());
d.eat();
d.sleep();
d.jump();
}
}
------------------------------------------------------------------------------------
結果:
Tom---4
貓吃魚
睡覺!
跳高貓
---------
旺財---5
狗吃肉
睡覺!
跳高狗
//接口,說英語
interface SpeakEnglish{
public abstract void say();
}
//抽象類,人
abstract class Person{
//姓名
private String name;
//年齡
private int age;
//無參構造
public Person() {
}
//帶參構造
public Person(String name,int age) {
this.name = name;
this.age = age;
}
//getXxx()/setXxx()
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("睡覺");
}
}
//抽象類,運動員
abstract class Athlete extends Person{
//無參構造
public Athlete() {
}
//帶參構造
public Athlete(String name,int age) {
super(name,age);
}
//抽象方法,學習
public abstract void study();
}
//抽象類,教練
abstract class Coach extends Person{
//無參構造
public Coach() {
}
//帶參構造
public Coach(String name,int age) {
super(name,age);
}
//抽象方法,教
public abstract void teach();
}
//具體類,乒乓球運動員
class TableAthlete extends Athlete implements SpeakEnglish{
//無參構造
public TableAthlete() {
}
//帶參構造
public TableAthlete(String name,int age) {
super(name,age);
}
//接口,說英語
public void say() {
System.out.println("說口語!");
}
//繼承吃飯
public void eat() {
System.out.println("乒乓球運動員吃飯!");
}
//繼承學習
public void study(){
System.out.println("乒乓球運動員學習");
}
}
//具體類,籃球運動員
class BasketballAthlete extends Athlete {
//無參構造
public BasketballAthlete() {
}
//帶參構造
public BasketballAthlete(String name,int age) {
super(name,age);
}
//繼承吃飯
public void eat() {
System.out.println("籃球球運動員吃飯!");
}
//繼承學習
public void study(){
System.out.println("籃球運動員學習");
}
}
//具體類,乒乓球教練
class TableCoach extends Coach implements SpeakEnglish{
//無參構造
public TableCoach() {
}
//帶參構造
public TableCoach(String name,int age) {
super(name,age);
}
//繼承吃飯
public void eat() {
System.out.println("乒乓球教練吃飯!");
}
//繼承教
public void teach() {
System.out.println("乒乓球教練教!");
}
//接口
public void say() {
System.out.println("乒乓球教練說英語");
}
}
//具體類,籃球教練
class BasketballCoach extends Coach{
//無參構造
public BasketballCoach() {
}
//帶參構造
public BasketballCoach(String name,int age) {
super(name,age);
}
//繼承吃飯
public void eat() {
System.out.println("乒乓球教練吃飯!");
}
//繼承教
public void teach() {
System.out.println("乒乓球教練教!");
}
}
public class Athletecoach {
public static void main(String[] args) {
TableAthlete ta = new TableAthlete();
ta.setName("李華");
ta.setAge(20);
System.out.println(ta.getName()+"---"+ta.getAge());
ta.eat();
ta.say();
ta.study();
ta.sleep();
System.out.println("---------");
BasketballAthlete ba = new BasketballAthlete("張三",19);
System.out.println(ba.getName()+"---"+ba.getAge());
ba.eat();
ba.study();
ba.sleep();
System.out.println("--------");
TableCoach tc = new TableCoach();
tc.setName("劉備");
tc.setAge(30);
System.out.println(tc.getName()+"---"+tc.getAge());
tc.eat();
tc.say();
tc.teach();
tc.sleep();
System.out.println("---------");
}
}
---------------------------------------------------------------------------------
結果:
李華---20
乒乓球運動員吃飯!
說口語!
乒乓球運動員學習
睡覺
---------
張三---19
籃球球運動員吃飯!
籃球運動員學習
睡覺
--------
劉備---30
乒乓球教練吃飯!
乒乓球教練說英語
乒乓球教練教!
睡覺
---------