構造器(構造方法)
方法名和類名一樣,但是沒有傳回值,void也不能加
**最好:**一個類如果重寫了有參構造,那麼最好機上一個無參構造,如果不加,可能會在繼承關系中出錯
作用:
- 使用new關鍵字,必須要有構造器(本質是在調用構造器)
- 一旦定義了一個有參構造,那麼無參構造必須顯示定義
- 一般用來初始化值
文法:
public class hello {
public String _name;
private int _age;
//構造器,也叫構造方法
public hello(String name, int age) {
this._name = name;
this._age = age;
}
}
在這裡,_age是私有的,哪怕在構造器賦了值,在别的類中建立對象也還是調用不了,而 _name就可以
面向對象三大特性:
(有繼承才有重寫,有重寫才有多态)
封裝:
意義:
- 提高程式的安全性,保護資料
- 隐藏代碼的實作細節
- 統一接口
- 系統可維護性增加
封裝(資料的隐藏):
通常,應禁止直接通路一個對象中的資料的實際表示,而應通過操作接口來通路,這成為資訊隐藏
記住這句話就夠了:屬性私有,get/set
示例:
在hello這個類中給它的屬性封裝:
public class hello {
//屬性私有
private String name;
private int age;
//提供一些可以操作這個屬性的方法
//提供一些public的get和set方法
//封裝的get方法,傳回值為封裝屬性的類型,且封裝屬性的首字母大寫
//get 獲得傳回的這個資料
public String getName(){
return this.name;
}
//封裝的set方法,傳回值為void,提供給外部進行的操作,屬性首字母大寫
//set 給這個屬性設定值,也可以加上條件對不合法的起輸入限制作用
public void setName(String name){
this.name =name;
}
}
在另一個類中,執行個體化hello類的對象,調用它的封裝屬性:
hello h= new hello();
h.setName("王志凱");//在另一個類通過設定的方法給屬性設值
System.out.println(h.getName());//得到傳回的值,并且輸出
結果:
王志凱
繼承:
在Java中所有的類都是object的子類。預設繼承object類
在Java中類隻能單繼承,沒有多繼承
文法:
extends:擴充。子類是父類的擴充
public class Student extends Person {
}
super:
注意點:
- super調用父類的構造方法,必須在構造方法的第一個
- super必須隻能出現在子類的方法和或者構造方法中
- super和this不能同時調用構造方法
super VS this
- 代表的對象不同
this:本身調用者這個對象
super:代表父類對象的應用
前提:
this:沒有繼承也可以使用
super:隻能在繼承條件下才能使用
構造方法的差別:
this():調用本類的構造方法
super():調用父類的構造方法
重寫(override):
重寫就是在子類裡建立一個和父類中相同的方法,但是裡面的方法體不同,這樣子,在對象調用的時候,就會調用到子類重寫的方法,而不會調用到父類的相同的方法
- 需要有繼承關系,子類重寫父類的方法
- 方法名必須相同,方法體可以不同
- 參數清單必須相同
- 修飾符:範圍可擴大,public>Protected>Default>private
- 抛出的異常:範圍,可以被縮小,但不能擴大:ClassNotFoundException–>Exception
- 重寫都是方法的重寫,和屬性無關,私有的方法無法重寫
- 非靜态的方法才能被重寫
靜态方法:方法的調用隻和左邊定義的資料類型有關
**非靜态方法:**才叫重寫
思考:為什麼需要重寫?
答:父類的功能子類不一定需要,或者不一定滿足,是以需要子類把父類的方法重寫一下,加上自己需要的功能
示例:
Application類:
public class Application {
public static void main(String[] args) {
Student s = new Student();//重點關注這裡
s.test();
Person p = new Student();//重點關注這裡
p.test();
}
}
Person類:
public class Person {
public static void test(){
System.out.println("person的test");
}
}
Student類:
public class Student extends Person {
public static void test(){
System.out.println("student的test");
}
}
輸出的結果:
student的test
person的test
**解析:**這說明,當方法是靜态方法的時候,調用方法隻與 Student s 和 Person p有關,也就是說當是靜态方法時,調用的方法隻和執行個體化語句中的:
Student s = new Student();
Person p = new Student();
左邊相關,是哪個類就是哪個類的方法,否則就是new的類的方法。
多态:
- 即同一方法可以根據發送對象的不同采用多種不同的行為方式
- 一個對象的 “實際類型”(如:new Person())是确定的,但可以指向對象的 “引用類型”(如:Person p )有很多
- 多态存在的條件:
- 有繼承關系
- 子類重寫了父類方法
- 父類的引用指向子類對象
A a= new B();
*
注意:
- 多态是方法的多态,屬性沒有多态性
- 如果父類的引用類型指向得失子類的對象,那麼通過父類的引用類型來調用的方法還是可以實作父類的功能的,雖然是指向了子類的,但因為子類是繼承了父類的方法的。
- 靜态方法:方法的調用隻和左邊定義的資料類型有關
- **非靜态方法:**才能重寫
通俗的說就是:
對象能執行的那些非靜态的方法,主要看對象左邊的類型,和右邊的關系不大,隻有左邊的類型有的非靜态的方法才可以實作,隻有右邊有的方法沒辦法實作。
B a= new B();//B 能調用的方法都是自己的或者繼承父類A的
A a= new B();//A 父類型的引用,可以指向子類,但是不能調用子類獨有的方法。
有static靜态,final常量,private私有修飾符的無法重寫,自然也就沒有多态
Instanceof
文法:A Instanceof B
A和B有關系嗎?有true,沒有false
用法:
有一個Student類繼承extends父類Person
Object o = new Student();
System.out.println(o instanceof Student);
System.out.println(o instanceof Person);
System.out.println(o instanceof Object);
System.out.println(o instanceof String);
結果:
true
true
true
false
類型轉換:
高轉低要強制轉換,低轉高自動轉換
父類高于子類
文法:
(Person)Student
Static
當通路的類中的變量是static變量時候,可以直接通過類名.來通路這個成員。
static方法隻會在一開始加載一次,之後不會再加載
抽象類:
- 抽象類,隻有抽象方法,沒有方法體。
- 子類如果繼承了抽象類,那麼抽象類的所有方法,子類都要去實作。(如果子類也是abstract,那就不用)
特點:
- 不能new出來這個抽象類,隻能靠子類去實作它
- 抽象類隻可以寫方法,沒有方法體
- 抽象方法必須在抽象類中
個人思考:
抽象類真正的作用是為了實作,他的目的是當父類某種方法毫無意義,但是又必須要有的時候占個位置,提醒子類一定要去實作。打個比方,電器有耗電标準,但是籠統的電器(父類)的耗電标準是毫無意義的,隻有具體到實際的某種電器(子類)才有意義,是以幹脆就不在電器(父類)中寫,由具體的電器(子類)來完成,但是耗電标準又是必須得實作的,是以需要電器(父類)為之提醒。這也是跟實際生活相符合的結果,是面向對象思維的展現。
(****就是當這個父類是抽象類的時候裡面定義了一個抽象函數(在傳回值前面加上abstract),裡面的函數沒有方法體,因為父類不知道每個子類需要實作什麼方法,是以子類隻需要建立一個和父類相同的函數方法,表示重寫父類的抽象方法,就可以自己來實作自己特有的函數方法體,而且子類必須都要重寫一遍抽象類(父類)的抽象方法****)
文法:
abstract
public abstract class Application {
public abstract test();//沒有方法體
}
接口:
聲明類的關鍵字是class,聲明接口的關鍵字是interface
接口連構造方法都沒有,自然沒法被執行個體化
普通類:隻有具體的實作
抽象類:具體實作和規範(抽象方法)都有
接口:隻有規範!自己無法寫方法,專業的限制,限制和實作分離
- 接口就是規範,定義得是一組規則,展現了現實世界“如果你是…則必須能…”的思想,如果你是天使,則必須能飛,如果你是汽車,則必須能跑,如果你是好人,則必須幹掉壞人,如果你是壞人,則必須欺負好人
- 接口的本質是契約,就像我們人間的法律一樣,制定好後,大家都遵守
- OO的精髓,是對對象的抽象,最能展現這一點的就是接口
文法:
interface 定義接口的關鍵字,代替class
implements 類繼承接口的關鍵字
示例:
UserService接口:
//interface 定義的關鍵字
public interface UserService {
//接口中的所有定義其實都是抽象的 public abstract
void run(String name);//可以不寫public
void delete(String name);
void update(String name);
}
Teacher接口:
public interface Teacher {
void teach();
void classBegin();
}
UserServiceImp繼承接口的類:
- 類可以實作接口, implements 實作接口
- 實作了接口的類,就需要重寫接口的方法
- 接口可以實作多繼承
//類可以實作接口, implements 實作接口
//實作了接口的類,就需要重寫接口的方法
//接口可以實作多繼承
public class UserServiceImp implements UserService,Teacher {
//UserService接口的抽象接方法,子類重寫接口的抽象方法
@Override
public void run(String name) {
System.out.println("我是運作");
}
@Override
public void delete(String name) {
System.out.println("我是删除");
}
@Override
public void update(String name) {
System.out.println("我是更新");
}
//Teacher接口的抽象方法,子類重寫接口的抽象方法
@Override
public void teach() {
System.out.println("我是教學");
}
@Override
public void classBegin() {
System.out.println("我是上課");
}
}
内部類:
- 在一個類的内部在定義一個類就是内部類,對于内部類來說,外面的類就是外部類
- 内部類可以實作外部類的私有屬性
用法:
要使用内部類,先要執行個體化外部類的對象,然後通過對象來執行個體化内部類
執行個體化外部類:
Student t = new Student();
執行個體化内部類:
Student t = new Student();
t.hand hand= t.new hand();//執行個體化内部類