day09-----------面向對象(傳智視頻)

/*
	final能夠修飾類,方法,變量
	
	特色:
		final能夠修飾類,該類不能被繼承。
		final能夠修飾方法,該方法不能被重寫。(覆蓋,複寫)
		final能夠修飾變量,該變量不能被從新賦值。由於這個變量其實常量。
		
	常量:
		A:字面值常量
			"hello",10,true
		B:自定義常量
			final int x = 10;
*/
/*
	面試題:final修飾局部變量的問題
		基本類型:基本類型的值不能發生改變。
		引用類型:引用類型的地址值不能發生改變,可是,該對象的堆內存的值是能夠改變的。
*/
/*
	多態:同一個對象(事物),在不一樣時刻體現出來的不一樣狀態。
	舉例:
		貓是貓,貓是動物。
		水(液體,固體,氣態)。
		
	多態的前提:
		A:要有繼承關係。
		B:要有方法重寫。
			其實沒有也是能夠的,可是若是沒有這個就沒有意義。
				動物 d = new 貓();
				d.show();
				動物 d = new 狗();
				d.show();
		C:要有父類引用指向子類對象。
			父 f =  new 子();
			
	用代碼體現一下多態。
	
	多態中的成員訪問特色:
		A:成員變量
			編譯看左邊,運行看左邊。
		B:構造方法
			建立子類對象的時候,訪問父類的構造方法,對父類的數據進行初始化。
		C:成員方法
			編譯看左邊,運行看右邊。
		D:靜態方法
			編譯看左邊,運行看左邊。
			(靜態和類相關,算不上重寫,因此,訪問仍是左邊的)
			
		因爲成員方法存在方法重寫,因此它運行看右邊。
*/
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) {
		//要有父類引用指向子類對象。
		//父 f =  new 子();
		Fu f = new Zi();
		System.out.println(f.num);
		//找不到符號
		//System.out.println(f.num2);
		
		f.show();
		//找不到符號
		//f.method();
		f.function();
	}
}
/*
	多態的弊端:
		不能使用子類的特有功能。
		
	我就想使用子類的特有功能?行不行?
		行。
		
	怎麼用呢?
		A:建立子類對象調用方法便可。(能夠,可是不少時候不合理。並且,太佔內存了)
		B:把父類的引用強制轉換爲子類的引用。(向下轉型)
		
	對象間的轉型問題:
		向上轉型:
			Fu f = new Zi();
		向下轉型:
			Zi z = (Zi)f; //要求該f必須是可以轉換爲Zi的。
*/
多態的問題理解:
	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("英雄聯盟");
		}
	}
	
	//Java培訓特別火,不少人來請孔子爹去講課,這一天孔子爹被請走了
	//可是還有人來請,就剩孔子在家,價格還挺高。孔子一想,我是否是能夠考慮去呢?
	//而後就穿上爹的衣服,帶上爹的眼睛,粘上爹的鬍子。就開始裝爹
	//向上轉型
	孔子爹 k爹 = new 孔子();
	//到人家那裏去了
	System.out.println(k爹.age); //40
	k爹.teach(); //講解論語
	//k爹.playGame(); //這是兒子才能作的
	
	
	//講完了,下班回家了
	//脫下爹的裝備,換上本身的裝備
	//向下轉型
	孔子 k = (孔子) k爹; 
	System.out.println(k.age); //20
	k.teach(); //講解論語
	k.playGame(); //英雄聯盟

靜態是隨着類的加載而加載的。
java

成員變量僅僅是該事物的外在特徵描述,而成員方法是該事物的功能描述。功能是內在特徵。面試

變量使用的是父類,方法是子類測試

/*
	ClassCastException:類型轉換異常
	通常在多態的向下轉型中容易出現
*/
class Animal {
	public void eat(){}
}

class Dog extends Animal {
	public void eat() {}
	
	public void lookDoor() {
	
	}
}

class Cat extends Animal {
	public void eat() {
	
	}
	
	public void playGame() {
		
	}
}

class DuoTaiDemo5 {
	public static void main(String[] args) {
		//內存中的是狗
		Animal a = new Dog();
		Dog d = (Dog)a;
		
		//內存中是貓
		a = new Cat();
		Cat c = (Cat)a;
		
		//內存中是貓
		Dog dd = (Dog)a; //ClassCastException
	}
}
/*
	多態練習:貓狗案例
*/
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("--------------");
		
		//演示錯誤的內容     //左大右小
		//Dog dd = new Animal();
		//Dog ddd = new Cat();
		//ClassCastException
		//Dog dd = (Dog)a;
	}
}
/*
	看程序寫結果:先判斷有沒有問題,若是沒有,寫出結果
	
	多態的成員訪問特色:
		方法:編譯看左邊,運行看右邊。
		
	繼承的時候:
		子類中有和父類中同樣的方法,叫重寫。
		子類中沒有父親中出現過的方法,方法就被繼承過來了。
*/
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();
	}
}

/*
愛
你
*/
/*
	抽象類的概述:
		動物不該該定義爲具體的東西,並且動物中的吃,睡等也不該該是具體的。
		咱們把一個不是具體的功能稱爲抽象的功能,而一個類中若是有抽象的功能,該類必須是抽象類。
		
	抽象類的特色:
		A:抽象類和抽象方法必須用abstract關鍵字修飾
		B:抽象類中不必定有抽象方法,可是有抽象方法的類必須定義爲抽象類
		C:抽象類不能實例化
			由於它不是具體的。
			抽象類有構造方法,可是不能實例化?構造方法的做用是什麼呢?
			用於子類訪問父類數據的初始化
		D:抽象的子類
			a:若是不想重寫抽象方法,該子類是一個抽象類。
			b:重寫全部的抽象方法,這個時候子類是一個具體的類。
			
		抽象類的實例化實際上是靠具體的子類實現的。是多態的方式。
			Animal a = new Cat();
*/

//abstract class Animal //抽象類的聲明格式
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) {
		//建立對象
		//Animal是抽象的; 沒法實例化
		//Animal a = new Animal();
		//經過多態的方式
		Animal a = new Cat();
		a.eat();
	}
}
/*
	抽象類的成員特色:
		成員變量:既能夠是變量,也能夠是常量。
		構造方法:有。
					用於子類訪問父類數據的初始化。
		成員方法:既能夠是抽象的,也能夠是非抽象的。
		
	抽象類的成員方法特性:
		A:抽象方法 強制要求子類作的事情。
		B:非抽象方法 子類繼承的事情,提升代碼複用性。
*/
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");
	}
}

class AbstractDemo2 {
	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();
	}
}

因爲子類有特有的內容,因此咱們用子類來測試this

/*
一個類若是沒有抽象方法,可不能夠定義爲抽象類?若是能夠,有什麼意義?
	A:能夠。
	B:不讓建立對象。

abstract不能和哪些關鍵字共存?
	private	衝突
	final	衝突	
	static	無心義
*/
abstract class Fu {
	public abstract void show();
	//非法的修飾符組合: abstract和private;abstract自己就是要讓重寫,private是不讓重寫的,因此衝突
	//private abstract void show();
	
	//非法的修飾符組合
	//final abstract void show();	
	
	//非法的修飾符組合
	//static abstract void show();
	
	public static void method() {
		System.out.println("method");
	}
}

class Zi extends Fu {
	public void show() {}
}

class AbstractDemo3 {
	public static void main(String[] args) {
		Fu.method();
	}
}
/*
	接口的特色:
		A:接口用關鍵字interface表示	
			interface 接口名 {}
		B:類實現接口用implements表示
			class 類名 implements 接口名 {}
		C:接口不能實例化
			那麼,接口如何實例化呢?
			按照多態的方式來實例化。
		D:接口的子類
			a:能夠是抽象類。可是意義不大。
			b:能夠是具體類。要重寫接口中的全部抽象方法。(推薦方案)
	
	因而可知:
		A:具體類多態(幾乎沒有)
		B:抽象類多態(經常使用)
		C:接口多態(最經常使用)
*/
//定義動物培訓接口
interface AnimalTrain {
	public abstract void jump();
}

//抽象類實現接口
abstract class Dog implements AnimalTrain {
}

//具體類實現接口
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();
	}
}
/*
	接口成員特色
		成員變量;只能是常量,而且是靜態的。
				默認修飾符:public static final
				建議:本身手動給出。
		構造方法:接口沒有構造方法。
		成員方法:只能是抽象方法。
				默認修飾符:public abstract
				建議:本身手動給出。
		
	全部的類都默認繼承自一個類:Object。
	類 Object 是類層次結構的根類。每一個類都使用 Object 做爲超類。
*/
/*
	類與類:
		繼承關係,只能單繼承,能夠多層繼承。
	類與接口:
		實現關係,能夠單實現,也能夠多實現。
		而且還能夠在繼承一個類的同時實現多個接口。
	接口與接口:
		繼承關係,能夠單繼承,也能夠多繼承。
*/
interface Father {
	public abstract void show();
}

interface Mother {
	public abstract void show2();
}

interface Sister extends Father,Mother {

}

//class Son implements 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");
	}
}

class InterfaceDemo3 {
	public static void main(String[] args) {
		//建立對象
		Father f = new Son();
		f.show();
		//f.show2(); //報錯
	
		Mother m = new Son();
		//m.show(); //報錯
		m.show2();
	}
}
抽象類和接口的區別:
A:成員區別
	抽象類:
		成員變量:能夠變量,也能夠常量
		構造方法:有
		成員方法:能夠抽象,也能夠非抽象
	接口:
		成員變量:只能夠常量
		成員方法:只能夠抽象
		
B:關係區別
	類與類
		繼承,單繼承
	類與接口
		實現,單實現,多實現
	接口與接口
		繼承,單繼承,多繼承
		
C:設計理念區別
	抽象類 被繼承體現的是:」is a」的關係。抽象類中定義的是該繼承體系的共性功能。
	接口 被實現體現的是:」like a」的關係。接口中定義的是該繼承體系的擴展功能。
/*
	老師和學生案例,加入抽菸的額外功能
	
	分析:從具體到抽象
		老師:姓名,年齡,吃飯,睡覺
		學生:姓名,年齡,吃飯,睡覺
		
		因爲有共性功能,咱們提取出一個父類,人類。
		
		人類:
			姓名,年齡
			吃飯();
			睡覺(){}
			
		抽菸的額外功能不是人或者老師,或者學生一開始就應該具有的,因此,咱們把它定義爲接口
		
		抽菸接口。

		部分老師抽菸:實現抽菸接口
		部分學生抽菸:實現抽菸接口
		
	實現:從抽象到具體
		
	使用:具體
*/
//定義抽菸接口
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("劉意",30);
		System.out.println(ss2.getName()+"---"+ss2.getAge());
		ss2.eat();
		ss2.sleep();
		ss2.smoke();
		
		//測試老師留給本身練習
	}
}
相關文章
相關標籤/搜索