1 Java類與對象
1.1 類
- 屬性:類的
成員變量
,作用範圍是整個類,有默認值。 - 功能:類的
成員方法
。
一般成員變量設爲private
, 成員方法爲public
.修飾符 class 類名{ //成員變量定義 修飾符 數據類型 變量名[ = 值] ; //成員方法定義 修飾符 返回值類型 方法名(參數列表){ ... //方法內容 } }
- 構造方法
修飾符 構造方法名(參數列表){ ... //構造方法實體 }
- 構造方法注意事項
- 構造方法沒有返回值類型和返回值。
- 構造方法名和類名相同。
- 構造方法在創建對象的時候執行一次,未自己定義構造方法時編譯器會創建一個默認構造方法,自己定義了則編譯器不會創建默認構造方法。
- 構造方法可以重載。
- 構造方法注意事項
static
關鍵字- static修飾類中的成員,該成員屬於該類,不屬於該類的某個對象。(對象的共享數據)
- 成員調用:
類名.成員
,也可以使用對象.成員
- static注意事項:
- 靜態不能調用非靜態。原因:靜態內容先於對象存在內存中,只能訪問靜態,不能用this/super。
但是可以創建對象來調用非靜態方法。public class Fu { public static int a = 1; public static void show() { System.out.println("This is superclass!!"); ceshi(); //編譯錯誤,靜態不能調用非靜態,而且這裏不能使用 this.ceshi(); //但是可以創建一個對象來調用非靜態方法 Fu f = new Fu(); f.ceshi(); } public void ceshi() { System.out.println("xixix"); } }
- 技巧:方法中未用到非靜態成員,推薦使用static修飾該方法。
- 靜態不能調用非靜態。原因:靜態內容先於對象存在內存中,只能訪問靜態,不能用this/super。
1.2 對象
對象是類的實例。
- 創建對象:
類名 對象名 = new 構造方法(參數列表);
- 匿名對象:沒有引用變量,只能使用一次。
new 構造方法(參數列表)
1.3 內部類
- 類寫在其他類內部,作爲成員內部類或局部內部類。
public class Outer{ //成員內部類 public class Inner{ public void show(){ System.out.println("This is an inner class!!"); } } }
- 非靜態內部類不能有靜態成員。
原因:JVM加載順序:類靜態成員類對象,要求靜態變量在對象創建之前完成, - 創建內部類引用對象:
外部類名.內部類名 變量 = 外部類對象.new 內部類構造方法(參數列表)
.Outer.Inner in = new Outer().new Inner(); in.show(); //調用內部類方法
- 在內部類中對內部類與外部類同名成員調用:
- 內部類成員:
this.成員
- 外部類成員:
外部類名.this.成員
package org.ywq.innerclass; public class Outer { private int a=1; //成員內部類 public class Inner{ private int a=2; public void inner() { int a=3; System.out.println(a); //output 3 System.out.println(this.a); //output 2 System.out.println(Outer.this.a); //output 1 } } }
- 內部類成員:
2 面向對象三大特徵
2.1 封裝
- 隱藏實現細節,對外提供可以訪問的方式。
- 方法、類、包都是封裝。
- 封裝要求將成員變量設爲private, 所以要添加
set變量名()
,get變量名()
成員方法對成員變量進行間接訪問。(private成員只能在本類中使用)public class Person{ private String name; private int age; //set方法 public void setName(String name){ this.name=name; } public void setAge(int age){ this.age=age; } //get方法 public String getName(){ return name; } public int getAge(){ return age; } }
this
關鍵字- this表示本類對象的引用、調用方法的對象,在類中可以省略不寫
(強烈不建議)
。 - 通過this可區分類中成員變量和局部變量同名。
this()
用法:調用本類的構造方法。(該語句必須是構造方法中第一個statement)class Person{ protected String name; protected int age; //default constructor public Person(){ this("Lili",1); //調用重載的構造方法Person(String name, int age) } //Overload constructor public Person(String name, int age){ this.name=name; this.age=age; } }
- this表示本類對象的引用、調用方法的對象,在類中可以省略不寫
2.2 繼承
子類擁有父類所有可繼承的變量和方法。
-
格式(
extends
關鍵字)class 子類 extends 父類{ .... }
-
繼承的注意事項
- Java
不允許多繼承
:一個類只能繼承一個父類。
原因:可能有安全隱患,如兩個類中有相同的方法。class A extends B,C{} //錯誤,不被允許
- Java
支持多重繼承
:B類繼承A類,C類繼承B類。class A{} class B extends A{} class C extends B{}
- Java
-
方法重寫(Override)
-
子類中對父類的方法進行重寫(方法名和參數列表保持一致)。
-
主要目的是保持父類功能,並添加子類的新功能。
class Son extends Father{ @Override public void showTelephone(){ super.showTelephone(); //父類的功能 System.out.println("New Function!!"); //添加子類的新功能 }
[特殊重寫方式1]——通過匿名對象重寫方法(僅臨時有效)
public class Test{ public static void main(String[] args) { //Way 1: Son son = new son(){ //Override public void showTelephone(){ ... //添加重寫方法體,僅臨時有效 } }; son.showTelephone(); //Way 2: new son(){ //Override public void showTelephone(){ ... //添加重寫方法體,僅臨時有效 } }.showTelephone(); } }
[特殊重寫方式2]——
Lamba表達式
(Java8新特性)- Lambda表達式相當於一個匿名方法,主要用來代替匿名對象方法重寫的繁瑣語法(也是創建一個對象實例)。
- Lambda表達式組成:
- 形參列表;(允許省略形參類型)
- 箭頭(->)
- 代碼塊。
- Java中Lambda表達式的目標類型必須是函數式接口——只有一個抽象方法的接口,但可以多個非抽象方法。
package org.ywq.lambda; interface Eatable { void taste(); } interface Flyable { void fly(String weather); } interface Addable { int add(int a, int b); } public class Test { public void eat(Eatable e) { System.out.println(e); e.taste(); } public void drive(Flyable f) { System.out.println("我正在駕駛: " + f); f.fly("[大晴天]"); } public void addTest(Addable add) { System.out.println("5和3的和爲: " + add.add(5, 3)); } public static void main(String[] args) { Test la = new Test(); //創建了Eatable接口實例,重寫taste()方法,代碼塊只有1條語句,可省略花括號和分號 la.eat(() -> System.out.println("真香!!")); // 創建了Flyable接口實例,重寫fly(String weather)方法,參數列表只有一個形參可以省略圓括號 la.drive(weather -> { System.out.println("今天天氣是:" + weather); System.out.println("飛機飛行正常!!!"); } ); // 創建了Addable接口實例,重寫add(int a, int b)方法,代碼塊只有1條語句,省略花括號,也可省略return la.addTest((a, b) -> a + b); } }
-
注意:重寫時子類方法權限要大於等於父類方法權限
class father{ public void show(){ } } class son extends father{ void show(){ //default權限 < public權限,編譯失敗 } }
四大權限:
public
>protected
>private
.
技巧:所有方法權限都設置爲public.
權限修飾符可以用來修飾類、類的成員變量、類的成員方法。
-
權限 | public | protected | private |
---|---|---|---|
本類 | Y | Y | Y |
本包中的類 Package | Y | Y | |
外部包中的類 World | Y |
super
關鍵字- 父類英文爲superclass
- super指父類的存儲空間,可以理解爲父類的引用對象。
super()
用法:調用父類的構造方法,完成父類成員的初始化操作。- 子類的構造方法第一行都有默認的隱式
super();
語句,除非是第一行使用this(參數列表);
語句。 super();
可以替換成手動寫的super(參數列表);
調用父類的相應構造方法。
- 子類的構造方法第一行都有默認的隱式
2.3 多態
-
表現:父類引用變量可以指向子類對象。(接口與實現類也滿足)
-
自動類型轉化。
父類 引用變量名 = new 子類();
-
多態規則:
- 成員變量
編譯、運行全看父類。 - 成員方法
編譯看父類,非靜態成員方法運行先看子類(重寫方法),子類未重寫再看父類。
靜態成員方法運行也看父類。(多態針對對象,而靜態成員與對象無關)
注:如果是子類特有方法,需要強制類型轉換才能調用。
- 成員變量
-
多態作用
在方法的參數列表中,可以使用父類數據類型,引用變量調用方法時參數可以是各個子類對象。
如:/******************接口 USB.java****************************/ /* *如果對接口不熟悉,可以參見本文 第4部分接口 內容 */ package org.ywq.duotai; public interface USB { public abstract void open(); public abstract void close(); }
/******************鼠標 Mouse.java****************************/ package org.ywq.duotai; public class Mouse implements USB{ @Override public void open() { System.out.println("打開鼠標"); } @Override public void close() { System.out.println("關閉鼠標"); } }
/******************鍵盤 Keyboard.java****************************/ package org.ywq.duotai; public class Keyboard implements USB{ @Override public void open() { System.out.println("打開鍵盤"); } @Override public void close() { System.out.println("關閉鍵盤"); } }
/******************電腦 Computer.java****************************/ package org.ywq.duotai; public class Computer { public static void open() { System.out.println("打開電腦"); } public static void close() { System.out.println("關閉電腦"); } //使用USB設備 public void useUSB(USB usb) { //成員方法參數類型爲USB接口類型,可以用Mouse和Keyboard引用變量 usb.open(); usb.close(); } }
/******************測試 Test.java****************************/ package org.ywq.duotai; public class Test { public static void main(String[] args) { Computer computer=new Computer(); computer.useUSB(new Mouse()); computer.useUSB(new Keyboard()); } }
-
instanceof
關鍵字- 用於判斷對象是否屬於某種數據類型。
對象 instanceof 數據類型 //返回 true 或 false
注意:數據類型爲類時,
對象 instanceof 父類
爲true.
如任意創建的類都是Object類的子類,所以對象 instanceof Object
始終是true. - 用於判斷對象是否屬於某種數據類型。
3 抽象類
-
使用
abstract
關鍵字。 -
定義抽象類
public abstract class Develop { public abstract void work(); }
-
抽象類作用:定義沒有方法體的方法,子類繼承抽象類並強制重寫抽象方法。
public class JavaEE extends Develop { @Override public void work() { System.out.println("JavaEE工程師在工作!"); } }
-
注意:
- 抽象類不能實例化對象。
- 如果子類繼承抽象類並只重寫了一部分抽象方法,則該子類還是抽象類。
- 抽象類中可以沒有抽象方法。
-
final
關鍵字- final意思是最終,不可變的。
- final可以修飾類、類的成員和局部變量。
- final修飾的類不能被繼承,但可以繼承其他類。
public final class Zi extends Fu{ }
- final修飾的方法不能被重寫(Override)
- final修飾的基本數據類型變量稱爲常量,只能被賦值一次。
final int a = 1;
- final修飾的引用變量,保持內存地址不變。
final Fu fu = new Zi(); fu = new Zi(); //編譯錯誤,final引用變量地址不能改變。
- final修飾的類不能被繼承,但可以繼承其他類。
4 接口
- 接口是功能的集合,是比抽象類更抽象的類,使用
interface
關鍵字。 - 接口只描述應該具備的方法,沒有具體實現。(接口內方法全是抽象方法)
- 接口中成員變量必須爲常量。
- 接口定義:
MyInterfaceDemo.class
文件:public interface MyInterfaceDemo{ //定義常量 public static final 數據類型 變量名 = 值; //定義抽象方法 public abstract 返回值類型 方法名(參數列表); }
- 接口實現(
implements
關鍵字)——接口和實現類public class 類 implements 接口{ 重寫接口中的抽象方法; }
- 接口注意事項
- 接口
允許多實現
:實現多個接口。
原因:接口中都是抽象方法,沒有安全隱患。public class C implements A,B{}
- 類可以繼承superclass同時實現接口
public class D extends C implements A,B{}
- 接口可以繼承接口,且支持多繼承。
public interface C extends A,B{}
- 接口
- 接口和抽象類的區別
- 抽象類是事物都具備的內容(共性),繼承體系是
is..a關係
。 - 接口是事物額外內容(特性),繼承體系是
like..a關係
。
- 抽象類是事物都具備的內容(共性),繼承體系是
5 包Package
- 包就是文件夾,存放類文件,一般將相同功能的類放到一個包中。
- 類中包的聲明格式(在class文件最開頭):
package 包名.包名.包名...;
- 導入包:
import 包名.包名...包名.類名;