static關鍵字
static 關鍵字可以用來修飾成員變量和成員方法假栓,被修飾的成員是屬于“類”寻行,而部署單單某個對象,也就是說匾荆,可以不依賴對象去調(diào)用
類變量
當‘static’修飾成員變量時拌蜘,該變量就是類變量杆烁,該類的每一個對象都共享同一個類變量的值,任何對象就可以更改該類變量的值简卧,但也可以在不創(chuàng)建對象的情況下對類變量進行操作兔魂。
格式:
static 數(shù)據(jù)類型 變量名
應用:static修飾的變量具有記憶功能
靜態(tài)方法
static關鍵字修飾成員方法,我們叫類方法
修飾符 static 返回值類型 方法名(參數(shù)列表){
}
- 靜態(tài)方法可以直接訪問類變量和靜態(tài)方法
- 靜態(tài)方法不能直接訪問普通成員方法和成員變量举娩,反之析校,成員方法可以直接訪問類變量和靜態(tài)方法。
-靜態(tài)方法中不能實驗this關鍵字
靜態(tài)方法智能訪問靜態(tài)成員
調(diào)用格式
被static修飾的成員建議通過類名直接訪問.
類名 類變量
類名 靜態(tài)方法()
演示
// 訪問類變量
System.out.println(Student.numberOfStudent);
// 調(diào)用靜態(tài)方法
Student.showNum();
靜態(tài)代碼塊
靜態(tài)代碼塊晓铆,定義在成員位置勺良,使用static修飾的代碼塊{}
- 位置:類中方法外
- 執(zhí)行:隨著類對加載而執(zhí)行且執(zhí)行一次,優(yōu)先于main方法和構造執(zhí)行
public class Game {
public static int number;
public static ArrayList<String> list;
// 作用骄噪,給類變量進行初始化賦值
static {
number = 2;
list = new ArrayList<String>();
list.add("zhangsan");
list.add("lisi");
}
}
總結 static關鍵字可以修飾變量尚困,方法,代碼塊链蕊,使用它的主要目的是我們不想創(chuàng)建對象的情況下去調(diào)用方法
Arrays類
import java.util.Arrays ; 其包含的所有方法均為靜態(tài)方法事甜,調(diào)用起來非常簡單
- Arrays.toString 返回數(shù)組內(nèi)容的字符串表示形式
- Arrays.sort(arr) 對指定的int類型數(shù)組進行排序
public static void main(String[] args) {
int[] arr = new int[10];
for (int i = 0; i < 10 ; i++) {
arr[i] = new Random().nextInt(100);
}
System.out.println("排序前" + Arrays.toString(arr));
// 升序排序
Arrays.sort(arr);
System.out.println("排序后" + Arrays.toString(arr));
}
Math類
Math類包含常用的基本數(shù)學運算方法,其包含的所有方法均為靜態(tài)方法滔韵,調(diào)用起來非常簡單
方法介紹:
public static void main(String[] args) {
double d1 = Math.abs(-5); // 絕對值
System.out.println(d1);
double d2 = Math.ceil(-3.3); //返回大于等于參數(shù)的最小整數(shù)
System.out.println(d2);
double d3 = Math.floor(-3.3);
System.out.println(d3); // 返回小于等于參數(shù)的最小整數(shù)
double d4 = Math.round(5.5); // 四舍五入
System.out.println(d4);
}
多態(tài)
多態(tài)是繼承逻谦,封裝之后面向?qū)ο蟮牡谌卣?br>
同一種行為,具有不同的表現(xiàn)形式
前提
- 1陪蜻、繼承或者實現(xiàn)【二選一】
- 2邦马、方法的重寫【意義體現(xiàn):不重寫無意義】
- 3、父類引用指向子類對象【格式體現(xiàn)】
體現(xiàn)
體現(xiàn)的格式
父類類型 變量名 = new 子類對象宴卖;
變量名.方法名
父類類型:指子類對象繼承的父類類型滋将,或者實現(xiàn)父接口類型
Fu f = new Zi();
f.method();
當使用多態(tài)方式調(diào)用方法時,首先檢查父類中是否有該方法症昏,如果沒有随闽,則編譯錯誤,如果有掘宪,執(zhí)行的是子類重寫后的方法魏滚。
演示
public abstract class Animal {
public abstract void eat();
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("小貓吃魚");
}
}
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃骨頭");
}
}
測試類
public class TestDy {
public static void main(String[] args) {
// 使用多態(tài)方式
Animal a1 = new Cat();
// 執(zhí)行的是子類重寫后方法
a1.eat();
Animal a2 = new Dog();
a2.eat();
}
}
多態(tài)的好處
在實際的開發(fā)過程中须眷,父類類型作為方法的形式參數(shù)惠拭,傳遞子類對象給方法棒呛,進行方法的調(diào)用秀鞭,更能體現(xiàn)多態(tài)多態(tài)的擴展性和遍歷性皱坛。
public abstract class Animal {
public abstract void eat();
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("小貓吃魚");
}
}
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃骨頭");
}
}
測試類
public class TestDy {
public static void main(String[] args) {
Cat c = new Cat();
Dog d = new Dog();
showCatEat(c);
showDogEat(d);
// 以上兩個方法贩猎,均可以被showAnimalEat(Animal animal)方法替代
// 執(zhí)行效果一致
// 實際的開發(fā)過程中噪馏, 父類類型作為方法的形式參數(shù), 傳遞子類對象給方法拟赊,
// 進行方法的調(diào)用桃移,更能體現(xiàn)出多態(tài)的擴展性與遍歷性借杰。
showAnimalEat(c);
showAnimalEat(d);
}
public static void showCatEat(Cat cat){
cat.eat();
}
public static void showDogEat(Dog dog){
dog.eat();
}
public static void showAnimalEat(Animal animal){
animal.eat();
}
}
由于多態(tài)特性的支持,showAnimalEat方法的Animal類型进泼,是Cat 和Dog的父類類型蔗衡,父類類型接收子類對象,當然可以把Cat對象和Dog對象傳遞給方法乳绕。
當eat方法執(zhí)行時绞惦,多態(tài)規(guī)定,執(zhí)行的是子類重寫的方法洋措,那么效果showCatEat和showDogEat方法一致济蝉。
不僅僅是替代,在擴展性方法呻纹,無論之后再多的子類出現(xiàn)堆生,我們都不需要編寫showXXXeat方法了,直接使用showAnimalEat都可以完成雷酪。
所以淑仆,多態(tài)的好處是程序編寫簡單,并有良好的擴展性哥力。
引用類型的轉換
向上轉型
- 向上轉型:當父類引用指向子類對象時蔗怠。
父類類型 變量名 = new 子類對象;
向下轉型
父類類型向子類類型向下轉化的過程吩跋,強制的
子類類型 變量名 = (子類類型) 父類變量名()
為什么轉型
當使用多態(tài)方式調(diào)用方法時寞射,首先檢查父類中是否有該方法,如果沒有锌钮,則編譯錯誤桥温,也就是說, 不能調(diào)用子類擁有梁丘, 而父類沒有的方法侵浸,編譯都錯誤, 更別胡搜運行了氛谜, 所以掏觉, 想要調(diào)用子類特有的方法, 必須向下轉型
public abstract class Animal {
public abstract void eat();
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("小貓吃魚");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃骨頭");
}
public void watchHouse(){
System.out.println("看家");
}
}
public static void main(String[] args) {
Animal a = new Cat(); // 向上轉型
a.eat();
// 為了避免轉型發(fā)生異常值漫,最好先做個判斷
// 變量名 instanceof 數(shù)據(jù)類型
// 向下轉型
if(a instanceof Cat){
Cat c = (Cat)a;
c.catchMouse();
}else if (a instanceof Dog){
Dog d = (Dog)a;
d.watchHouse();
}
}
接口(interface)
是Java中一種引用類型澳腹, 是方法集合, 如果類的內(nèi)部封裝了成員變量、構造方法和成員方法酱塔,那么接口的內(nèi)部主要就是封裝了方法沥邻。
- 包含抽象方法(JDK7以前)
- 默認方法和靜態(tài)方法(JDK8)
- 私有方法(JDK9)
接口也會被編譯成.class, 但是接口不是類。
使用接口延旧,不能創(chuàng)建對象谋国,但是可以被實現(xiàn)(implements), 類似繼承迁沫,一個實現(xiàn)接口的類,同樣需要實現(xiàn)接口的所有抽象方法捌蚊,否則他必須是一個抽象類集畅。
定義格式
public interface 接口名{
// 抽象方法
// 默認方法
// 靜態(tài)方法
// 私有方法
}
含有抽象方法
public interface InterFaceDemo {
public abstract void method();
}
可以省略abstract
public interface InterFaceDemo {
public void method();
}
含有默認方法和靜態(tài)方法
- 默認方法: 使用 default修飾, 不可以省略缅糟,供子類調(diào)用或者子類重寫
- 靜態(tài)方法:使用 static 修飾挺智,供接口直接調(diào)用
public interface InterFaceDemo {
public default void method(){
// 執(zhí)行語句
}
public static void method2(){
// 執(zhí)行語句
}
}
含有私有方法和私有靜態(tài)方法
供接口中的默認方法或者靜態(tài)方法調(diào)用
public interface InterFaceDemo {
private void method(){
// 執(zhí)行語句
}
}
基本實現(xiàn)
類與接口的關系為實現(xiàn)關系, 即類實現(xiàn)接口窗宦,該類叫做實現(xiàn)類赦颇, 也可以被稱為接口的子類.
非抽象子類實現(xiàn)接口:
1.必須重寫接口中所有的抽象方法
2.繼承了接口的默認方法, 可以直接調(diào)用赴涵,也可以重寫
class 類名 implements 接口名{
// 重寫接口中所有的抽象方法
//重寫接口的默認方法[可選]
}
抽象方法的使用
public interface LiveAble {
// 定義抽象方法
public abstract void eat();
public abstract void sleep();
}
實現(xiàn)類
public class Animal implements LiveAble {
@Override
public void eat() {
System.out.println("就知道吃");
}
@Override
public void sleep() {
System.out.println("還睡呀");
}
}
測試
public class TestInterface {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
a.sleep();
}
}
默認方法
public default void fly(){
System.out.println("飛飛飛");
}
重寫默認方法
public class Animal implements LiveAble {
@Override
public void eat() {
System.out.println("就知道吃");
}
@Override
public void sleep() {
System.out.println("還睡呀");
}
@Override
public void fly() {
System.out.println("左右飛");
}
}
測試
public class TestInterface {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
a.sleep();
a.fly(); // 調(diào)用默認方法
}
}
靜態(tài)方法
public static void run(){
System.out.println("嗷嗷跑");
}
public class Animal implements LiveAble {
// 無法重寫靜態(tài)方法
}
測試
public class TestInterface {
public static void main(String[] args) {
LiveAble.run();
}
}
私有方法
- 私有方法:只有默認方法可以調(diào)用
- 私有靜態(tài):默認方法和靜態(tài)方法可以調(diào)用
存在的意義: 當接口中存在多個默認方法媒怯,并且方法中有重復的內(nèi)容,可以抽取成一個私有方法髓窜,供默認方法調(diào)用扇苞。
public default void fly(){
System.out.println("飛飛飛");
func1();
func2();
}
private void func1(){
System.out.println("func1");
}
private void func2(){
System.out.println("func2");
}
接口的多實現(xiàn)
一個類只能繼承一個類, 但是一個類可以實現(xiàn)多個接口
一個類可以繼承一個父類寄纵, 同時實現(xiàn)多個接口
class 類名 [extends 類名] implements 接口1鳖敷,接口2,接口3...{
}
抽象方法
接口中有多個抽象方法程拭, 實現(xiàn)類必須重寫所有抽象方法定踱, 如果抽象方法有重名的,只需要重寫一次恃鞋。
默認方法
接口中有多個默認方法時崖媚,實現(xiàn)類都可以繼承使用, 如果默認方法有重名的山宾, 必須重寫一次
靜態(tài)方法
接口中存在同名的靜態(tài)方法并不會沖突至扰, 因為使用接口名調(diào)用
優(yōu)先級
當一個類,既繼承了一個父類资锰, 又實現(xiàn)了多個接口時敢课,父類中的成員方法與接口中的默認方法重名, 子類就近選擇中心父類的成員方法
接口的多繼承
一個接口可以繼承多個多個接口, 使用extends直秆, 如果有重名的, 子接口只需要重寫一次即可
總結
- 接口中濒募, 無法定義成員變量, 但是可以定義常量圾结,其值不可該表瑰剃,默認使用public static final 修飾
- 接口中, 沒有構造方法筝野,不能創(chuàng)建對象
- 接口中晌姚, 沒有靜態(tài)代碼塊