面向对象阶段语法
成員變量和局部變量的區別?
1.在類中的位置不同
成員變量:在類中方法外
局部變量:在方法定義中或者方法聲明上
2.在內存中的位置不同
成員變量:在堆內存
局部變量:在棧內存
3.生命周期不同
成員變量:隨著對象的創建而存在,隨著對象的消失而消失
局部變量:隨著方法的調用而存在,隨著方法的調用完畢而消失
4,初始化值不同
成員變量:有默認初始化值
局部變量:沒有默認初始化值,必須定義,賦值,然后才能使用
注意事項:
局部變量名稱和成員變量名稱可以一樣,在方法中使用的時候,采用的是就近原則
形式參數的問題:
基本類型:形式參數的改變不影響實際參數
引用類型:形式參數的改變直接影響實際參數
匿名對象的應用場景:
new Student().show();
1.調用方法,僅僅只調用一次的時候,那么這種匿名調用有什么好處嗎?
有,匿名對象調用完畢就是垃圾,可以被垃圾回收器回收
2.匿名對象可以作為實際參數傳遞
封裝概述:
是指隱藏對象的屬性和實現細節,僅對外提供公共訪問方式。
好處;隱藏實現細節,提供公共的訪問方式
提高了代碼的復用性
提高了代碼的安全性
原則:
將不需要對外提供的內容都隱藏起來
把屬性隱藏,提供公共的方法對其訪問
private關鍵字:
是一個權限修飾符
可以修飾成員(成員變量和成員方法)
被private修飾的成員,只能在本類中才能訪問。
private最常見的應用
把成員變量用private修飾,提供對應的getXXX()setXXX()方法
構造方法的注意事項:
1.如果我們沒有給出構造方法,系統將自動提供一個無參構造方法
2.如果我們給出了構造方法,系統將不再提供默認的無參構造方法
給成員變量賦值有兩種方法:
1.利用setXXX()方法賦值,這種方式調用的一般是無參的構造函數,利用 對象名.setXXX("林青霞");
2.利用帶有參數的構造方法賦值 通過調用有參構造函數,在創建對象的時候,直接賦值
?
class Student{
private String name = "林青霞";
private int age = 27;
public Student(){
name = "劉意";
age = 30;
}
}
class StudentDemo{
public static void main(String [] args){
Student s = new Student();
}
}
Student s = new Student();做了哪些事情
1.把Student.Class文件加載到內存
2.在棧內存給s變量開辟一個空間
3.在堆內存為學生對象申請一個空間
4.給成員變量進行默認初始化 null 0
5.給成員變量進行顯示初始化 林青霞 27
6.通過構造方法給成員變量進行初始化 劉意 30
7.數據初始化完畢,然后把堆內存的地址值賦值給棧內存的S變量
變量什么時候定義為成員變量;
如果這個變量是用來描述這個類的信息的,那么,該變量就應該定義為成員變量
變量到底定義在哪里好?
變量的范圍越小越好,因為能及時被回收。
?
static的特點(它可以修飾成員變量,也可以修飾成員方法)
1.隨著類的加載而加載
2.優先于對象存在(不用創建對象,它修飾的成員就能使用)
3.被類的所以對象共享
4.可以通過類名調用
static關鍵字的注意事項;
1.在靜態方法中是沒有this關鍵字的
如何理解呢?
靜態是隨著類的加載而加載,this是隨著對象的創建而存在
2.靜態方法只能訪問靜態的成員變量和靜態的成員方法
靜態方法:
無論是訪問成員變量還是都成員方法,都必須是靜態的
非靜態方法:
訪問靜態和非靜態都可以
簡單記:靜態只能訪問靜態
靜態變量和成員變量的區別:
所屬不同
靜態變量直屬于類,所以也成為類變量
成員變量屬于對象,所以也稱為實例變量
內存中位置不同
靜態變量存儲于方法區的靜態區
成員變量存儲于堆內存
內存出現時間不同
靜態變量隨著類的加載而加載,隨著類的消失而消失
成員變量隨著對象的創建而存在,隨著對象的消失而消失
調用不可
靜態變量可以通過類名調用,也可以通過對象調用
成員變量只能通過對象名調用
main方法的講解:
public static void main(String [] args)
public :公共的,訪問權限最大,由于main方法是被jvm調用,所以權限要大
static:靜態的,不需要創建對象,通過類名就可以,方便jvm的調用
void:因為我們曾經說過,方法的返回值是返回給調用者,而main方法是被jvm調用,所以返回內容給jvm沒有意義
main:是一個常見的方法入口,虛擬機認識的名字
String[] args:這是一個字符串數組,值去哪里了?
這個東西到底有什么用?怎么給值?
這個東西早期是為了接收鍵盤入錄的數據的,后面才有了Scanner
格式是:
java MainDemo hello world java
如何制造一個說明書呢?
1.寫一個工具類
2.對這個類加入文檔注釋
3.用工具解析文檔注釋
4.格式 javadoc -d 目錄 -author -version ArrayTool.java
目錄:就可以寫一個文件夾的路徑
制作幫助文檔出錯:
找不到可以文檔化的公共或受保護的類:告訴我們類的權限不夠
?
如何查看api文檔
1.打開幫助文檔
2.點擊顯示,找到索引,看到輸入框
3.知道你要找誰?以Scanner為例
4.在輸入框里面輸入Scanner,然后回車
5.看包
java.lang包下的類不需要導入,其他的全部要導入
要導入:
java.util.Scanner
6.再簡單的看看類的解釋和說明,別忘了看看該類的版本
7.看類的結構
成員變量 字段摘要
構造方法 構造方法摘要
成員方法 方法摘要
8.構造方法
1.有構造方法 就創建對象
2.沒有構造方法 成員可能都是靜態的
9.看成員方法
1.左邊
是否靜態:如果靜態,可以通過類名調用
返回值類型:人家返回什么,你就用什么接收
2.右邊
看方法名:方法名稱不要寫錯
參考列表:人家要什么,你就給什么,人家要幾個,你就給幾個
?
代碼塊:在java中,使用{}括起來的代碼被稱為代碼塊
根據其位置和聲明的不同,可以分為:
局部代碼塊:局部位置,用于限定變量的生命周期
構造代碼塊:在類的成員位置,用{}括起來的代碼,每次調用構造方法執行前,都會先執行構造代碼塊
靜態代碼塊:在類的成員位置,用{}括起來的代碼,只不過它用了static修飾
作用:一般是對類進行初始化
面試題:靜態代碼塊,構造代碼塊,和構造方法的執行順序?
靜態代碼塊-》構造代碼塊-》構造方法
靜態代碼塊:只執行一次
構造代碼塊:每次調用構造方法都執行
繼承概述:
把多個類中相同的內容給提取出來定義到一個類中
如何實現繼承呢?
java提供了關鍵字:extends
格式:
class 子類名 extends 父類 {}
好處:
1.提高了代碼的復用性
2.提高了代碼的維護性
3.讓類與類之間產生了關系,是多態的前提。
類與類產生了關系,其實也是繼承的一個弊端:類的耦合性增強了
開發的原則:低耦合,高內聚
耦合:類與類的關系
內聚:就是自己完成某件事情的能力
java只支持單繼承,不支持多繼承
一個類只能有一個父類,不可以有多個父類
java支持多層繼承(繼承體系),
繼承的注意事項:
1.子類只能繼承父類所有非私有的成員(成員方法和成員變量)
2.子類不能繼承父類的構造方法,但是可以通過super關鍵字去訪問父類構造方法
3.不要為了部分功能而去繼承
class A{
public void show1(){}
public void show2(){}
}
class B{
public void show2(){}
public void show3(){}
}
我們發現B類中出現了和A類一樣的show2()方法,所以,我們采用繼承
class B extendx A{
public void show3(){}
}
這樣其實不好,因為這樣你不但有了show2(),還多了show1(),有可能show1()不是你想要的
那么我們什么時候考慮使用繼承呢?
繼承其實體現的是一種關系:is a
person
Student
Teacher
繼承中成員變量的關系
1.子類中的成員變量和父類中的成員變量名稱不一樣,這個簡單
2.子類中的成員變量和父類中的成員變量名稱一樣,這個怎么玩呢?
在子類方法中訪問一個變量的查找順序:
1.在子類方法的局部范圍,有就使用
2.在子類的成員范圍,有就使用
3.在父類的成員范圍找,有就使用
4.如果還找不到,就報錯
this和super的區別?
this代表本類對象的引用
super代表父類存儲空間的標識(可以理解為父類引用,可以操作父類的成員)
怎么用呢?
1.調用成員變量
this.成員變量 調用本類的成員變量
super.成員變量 調用父類的成員變量
2.調用構造方法
this(...)調用本類的構造方法
super(...)調用父類的構造方法
3.調用成員方法
this.成員方法,調用本類的成員方法
super.成員方法,調用父類的成員方法
繼承中構造方法的關系?
1.子類中所有的構造方法默認都會訪問父類中空參數的構造方法
2.為什么呢?
因為子類會繼承父類中的數據,可能還會使用父類的數據,
所以,子類初始化之前,一定要先完成父類數據的初始化。
注意:子類每一個構造方法的第一條語句默認都是:super();
如果父類沒有無參構造方法,那么子類的構造方法會出現什么現象呢?如何解決呢?
會報錯:
如何解決呢?
1.在父類中加一個無參構造方法
2.通過使用super關鍵字去顯示調用父類的帶參構造方法
3.子類通過this去調用本類的其他構造方法(前提是子類中其他的構造方法中,
一定要有一個區訪問了父類的構造方法,否則父類數據就沒有初始化)
注意事項:
this(...)或者super(...)必須是第一條語句
如果不是放在第一條語句上,就可能對父類的數據進行了多次初始化(為什么呢?因為默認第一條語句會隱含調用父類的無參構造方法),所以必須放在第一條語句上。
繼承中成員方法的關系:
1.子類中的方法和父類中的方法聲明不一樣,這個簡單,直接調用
2.子類中的方法和父類中的方法聲明一樣,這個該怎么玩呢?
通過子類調用方法:
1.先找子類中,看有沒有這個方法,有就使用
2.再看父類中,有沒有這個方法,有就使用
3.如果沒有就報錯
方法重寫:子類中出現了和父類中方法聲明一模一樣的方法
方法重載:在同一個類中出現的方法名一樣,參數列表不同,與返回值無關
子類對象調用方法的時候:先找子類本身,再找父類
方法重寫的應用:
當子類需要父類的功能,而功能主體子類有自己特有的內容時,
可以重寫父類的方法,這樣,既沿襲了父類的功能,又定義了子類特有的內容
方法重寫的注意事項:
1.父類中私有方法不能被重寫
因為父類私有方法根本就無法繼承
2.子類重寫父類方法時,訪問權限不能更低
最好是一致
3.父類靜態方法,子類也必須通過靜態方法進行重寫
其實這個算不上方法重寫,但是現象確實如此
子類重寫父類方法的時候,最好聲明是一模一樣的
方法重寫和方法重載的區別?方法重載能改變返回值類型嗎?
方法重寫:
在子類中,出現和父類中一模一樣的方法聲明的現象
方法重載:
同一個類中,出現的方法名相同,參數列表不同的現象
方法重載能改變返回值類型,因為它和返回值類型無關
override:方法重寫
overload:方法重載
由于繼承中方法有一個現象:方法重寫
所以,父類的功能,就會被子類給覆蓋
有些時候,我們不想讓子類去覆蓋父類的功能,
這個時候,針對這種情況,java就提供了一個關鍵字:final
final:最終的意思。常見的是它可以修飾類,方法,變量
特點:
final可以修飾類,該類不能被繼承
final可以修飾方法,該方法不能被重寫
final可以修飾變量,該變了不能被重新賦值,因為這個變量其實是常量
常量:1.字面值常量 “hello”,10,true
2.自定義常量
final int x = 10;
注意,權限修飾符public,private等修飾局部變量是沒有意義的,
因為局部方法本身就是封裝的,談不上要不要訪問。
面試題:final修飾局部變量的問題
基本類型;基本類型的值不能發生改變
引用類型:引用類型的地址值不能發生改變,
但是,該對象的堆內存的值是可以改變的
多態:同一個對象,在不同時刻體現出來的不同狀態
多態的前提:
1.要有繼承關系
2.要有方法重寫
3.要有父類引用指向子類對象
父 f = new 子();
多態中的成員訪問特點:
1.成員變量
編譯看左邊,運行看左邊
2.成員方法
編譯看左邊,運行看右邊
3.構造方法
創建子類對象的時候,訪問父類的構造方法,對對象的數據進行初始化
4.靜態方法
編譯看左邊,運行看左邊
靜態和類相關,算不上重寫,所以,訪問還是左邊的
由于成員方法存在方法重寫,所以它運行看右邊
多態的好處:
1.提高了代碼的維護性(繼承保證)
2.提高了代碼的擴展性(多態保證)
多態的弊端:
不能使用子類的特有功能(因為在調用成員方法的時候,編譯要看左邊,一旦調用子類的特有功能,在父類中沒有,就會編譯失敗)
但是我就是想使用子類的特有功能,行不行?
行
怎么用呢?
1.創建子類對象調用方法即可(可以,但是意味著要創建新的對象,浪費內存)
2.把父類的引用強制轉換為子類的引用(向下轉型)
對象間的轉型問題:
向上轉型:
Fu f = new Zi();
向下轉型
Zi z = (Zi)f();//要求該f必須是能夠轉換為Zi的
?
抽象類的概述:
動物不應該定義為具體的東西,而且動物中的吃,睡等也不應該是具體的
我們把一個不是具體的功能稱為抽象功能,而一個類中如果有抽象功能,該類必須是抽象類
抽象類的特點;;
1, 抽象類和抽象方法必須用abstract關鍵字修飾
2.抽象類中不一定有抽象方法,但是有抽象方法的類一定是抽象類
3。抽象類不能實例化,因為它不是具體的
抽象類有構造方法,但是不能實例化,那么構造方法的作用是什么呢?
用于子類訪問父類數據的初始化
4.抽象類的子類
1.如果不想重寫抽象方法,那么該子類也必須是一個抽象類
2.如果重寫了所有的抽象方法,這個時候子類是一個具體的類
抽象類的實例化其實是靠具體額子類實現的,也就是多態
Animal a = new Cat();
抽象類成員的特點
成員變量:既可以是變量,也可以是常量
構造方法:有,用于子類訪問父類數據的初始化
成員方法:既可以是抽象的,也可以是非抽象的
抽象類成員方法的特性:
1.抽象方法 強制性要求子類做的事情
2.非抽象方法 子類繼承的事情,提高了代碼的復用性
一個類如果沒有抽象方法,可不可以定義為抽象類,如果可以,有什么意義?
答,可以,作用就是不讓創建對象唄
abstract不能和哪些關鍵字共存?
private,沖突,因為你加了private,子類怎么繼承啊,都沒有權限,而定義抽象類,就是要子類去實現的
final 就是終止,都終止了抽象干嗎呀,誰能實現的了啊
static用static修飾的方法可以用類名去調用,可定義抽象類,抽象方法都沒具體實現,你用類名去調用有什么意義啊
?
接口的特點:
1.接口用關鍵字interface表示
interface 接口名
2.類實現接口用implements 接口名{}
class 類名 implements 接口名{}
3.接口不能實例化
那么,接口如何實例化呢?
按照多態的方式來實例化
4.接口的子類
可以是抽象類,但是意義不大。
可以是具體類,要重寫接口中的所有的抽象方法
由此可見:
1.具體類多態(幾乎沒有為了講課需要)
2.抽象類多態(常用)
3.接口多態(最常用)
接口成員特點:
成員變量:只能是常量,并且是靜態的
默認修飾符:public static final
建議:自己手動給出
構造方法:接口沒有構造方法,因為接口主要是擴展功能的,而沒有具體存在
成員方法:只能是抽象方法
默認修飾符:public abstract
建議:自己手動給出
所有的類都默認繼承一個類:Object
類Object是類層次結構的根類,每個類都使用Object作為超類
類與類:
繼承關系,只能是單繼承,可以多層繼承
類與接口:
實現關系,可以單實現,也可以多實現
接口與接口:
繼承關系,可以單繼承,也可以多繼承
抽象類與接口的區別:
1.成員區別
抽象類:
成員變量:可以是變量,也可以是常量
構造方法:有
成員方法:可以抽象,也可以非抽象
接口:
成員變量:只能是常量
構造方法:壓根沒有好吧
成員方法:只可以是抽象的
2.關系區別
類與類
繼承,單繼承
類與接口
實現,單實現,多實現
接口與接口
繼承,單繼承,多繼承
3.設計理念區別
抽象類
被繼承體現的是:“is a”的關系
抽象類中定義的是該繼承體系的共性功能
接口
被實現體現的是:"like a"的關系,
接口中定義的是該繼承體系的擴展功能
形式參數:
基本類型(這個直接使用就可以)
引用類型:
類名:需要的是該類的對象
抽象類:需要的是該抽象類的子類對象
接口:需要的是該接口的實現類的對象
?
包:
1.其實就是文件夾
2.作用
1.把相同的類名放到不同的包中
2.對類進行分類管理
包的定義:
pack 包名;
多級包用.分開即可
例如:package.cn.itcast;
注意事項:
1.package語句必須是程序的第一條可執行的代碼
2.package語句自一個java文件夾中只能有一個
3.如果沒有package,默認表示無名包
帶包的編譯和運行
1.手動式
1.編寫一個帶包的java文件
2.通過javac命令編譯該java文件
3.手動創建包名(去創建文件夾)
4.把b步驟的class文件放到c步驟的最底層包
5.回到和包根目錄在同一目錄的地方,然后(帶包)運行
2.自動式
1.編寫一個帶包的java文件
2.javac編譯的時候帶上-d即可
javac -d .helloworld.java
3.回到和包根目錄在同一目錄的地方,然后(帶包)運行
?
導包概述
不同包下的類之間的訪問,我們發現,每次是使用不同包下的類的時候,都需要加包的路徑,比較麻煩,這個時候,java就提供了導包的功能
修飾符:
權限修飾符:private,默認,protected,public
狀態修飾符:static,final
抽象修飾符:abstract
類:
權限修飾符:默認修飾符,public
狀態修飾符:final
抽象修飾符:abstract
用的最多的是:public
成員變量:
權限修飾符:private,默認的,protected,public
狀態修飾符:static,final
用的最多的就是:private
構造方法
權限修飾符:private,默認的,protected,public
用的最多的是public
成員方法
權限修飾符:private,默認的,protected,public
狀態修飾符:static,final
抽象修飾符:abstract
用的最多的是:public
內部類概述:
把類定義在其他類的內部,這個類就被稱為內部類
舉例;在A類中定義了一個類B,類B就是內部類
內部類的訪問特點:
1.內部類可以直接訪問外部類的成員,包括私有
2.外部類要訪問內部類的成員,必須創建對象
內部類的分類:
成員內部類
局部內部類
成員內部類:
如何直接訪問內部類的成員
外部類名.內部類名 對象名 = 外部類.內部類對象
Outer.Inner oi = new Outer().new Inner();
成員內部類的修飾符:
private 為了保證數據的安全性
static 為了方便訪問數據
注意:靜態內部類訪問的外部類數據必須用靜態修飾,因為靜態只能訪問靜態
內部類可以用靜態修飾,是因為內部類可以看出是外部類的成員
成員內部類被靜態修飾后的訪問方式是:
外部類名.內部類名. 對象名 = new 外部類名.內部類名();
Outer.Inner oi = new Outer.Inner();
oi.show();
或者可以使用另外一種調用方法
Outer.Inner.show();
為什么加了static就要用類名呢,不是之前的對象呢,你都靜態了。創造個什么對象啊
面試題:
class Outer{
public int num = 10;
class Inner{
public int num = 20;
public void show(){
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(new Outer().num);
或者是 System.out.println(Outer.this.num);
}
}
}
注意事項:
1.內部類和外部類沒有繼承關系
2.通過外部類名限定this對象
局部內部類:
1.可以直接訪問外部類的成員
2.在局部位置,可以創建內部類對象,通過對象調用內部類方法,來使用局部內部類的功能
注意事項:局部內部類訪問局部變量必須用final,為什么呢?
因為局部變量是隨著方法的調用而調用,隨著調用完畢而消失
而堆內存的內容并不會立即消失,所以,我們加final修飾,加final后,這個變量就成了常量,既然是常量,你消失了,我在內存中存儲的就是數據20,所以還有數據使用
匿名內部類
就是內部類的簡化寫法
前提:存在一個類或者接口
這里的類可以是具體類,也可以是抽象類
格式:
new 類名或者接口名(){
重寫方法;
}
匿名內部類的本質是什么呢?
是一個繼承類或者實現了該接口的子類匿名對象
//用法一
interface Inter{
public abstract void show();
}
class Outer{
public void methoh(){
new Inter(){
pubic void show(){
System.out.println("show");
}
}.show();//第一種方法,這樣直接調用
}
}
class InnerClassDemo{
public static void main(String [] args){
Outer o = new Outer();
o.method();
}
}
//用法二
interface Inter{
public abstract void show();
}
class Outer{
public void methoh(){
Inter i = new Inter(){ //第二種采用多態
pubic void show(){
System.out.println("show");
}
}.show();
}
i.show();//利用多態調用
}
class InnerClassDemo{
public static void main(String [] args){
Outer o = new Outer();
o.method();
}
}
?
轉載于:https://www.cnblogs.com/Deleting/p/5068633.html
總結
- 上一篇: Spring 注解配置
- 下一篇: PHP $_REQUEST获取表单提交的