⑦Java SE知识点回顾与小结(面向对象)
Java SE 面向?qū)ο?/strong>
一.面向?qū)ο蟮膬?yōu)點:
? 1)面向?qū)ο蟮乃季S方式更貼近于現(xiàn)實生活的思維方式
? 2)面向?qū)ο笏季S方式更體現(xiàn)于管理者,面向過程體現(xiàn)于執(zhí)行者
? 3)可以將復(fù)雜的問題簡單化
二.面向?qū)ο筇岢隽?個概念:
? 以面向?qū)ο蟮乃季S方式編程就是讓程序和現(xiàn)實生活掛起聯(lián)系
? 類:一類或一系列事物的模板(定義的是一系列事物的共性) 對象:現(xiàn)實生活中真實存在的某個事物
? 沒有類就沒有辦法創(chuàng)建對象( 沒有圖紙就沒辦法造車)
三.自定義類:
? 根據(jù)一系列事物分析:
? 第一步分析:手機能做什么? 打電話,上網(wǎng),聊天,發(fā)信息,聽歌… 動詞,功能—>成員方法定義功能
? 第二步分析:手機的特征? 顏色,品牌,尺寸,價錢… 名詞,屬性–>成員變量
1)自定義類的創(chuàng)建
實例:
pubic class 類名{//屬性修飾符 數(shù)據(jù)類型 變量名=變量值;//功能修飾符 返回值類型|void 方法名(參數(shù)列表){方法體;}}成員不加static手機{顏色;品牌;價格;打電話(){}} /*自定義小汽車類屬性:顏色 品牌 輪胎個數(shù)功能: 跑 */ public class Car{ //顏色public String color;//品牌public String brand;//個數(shù)public int num;//跑public void run(){System.out.println("一輛"+color+"的"+num+"個轱轆的"+brand+"在跑....");} }2)使用自定義類
? 1.導(dǎo)包
? 1)java.lang包下的內(nèi)容可直接使用不需要導(dǎo)包 2)同包下的類不需要導(dǎo)包
? 2.創(chuàng)建這個類型的一個變量|引用 創(chuàng)建對象------->new
? 引用數(shù)據(jù)類型 變量名 = new 引用數(shù)據(jù)類型();
? 3.使用內(nèi)容
? 變量名.屬性名字
? 變量名.方法名字(實參)
實例:
/*測試小汽車類 通過new關(guān)鍵字創(chuàng)建對象 */ public class CarTest{ public static void main(String[] args){//1.創(chuàng)建一個小汽車對象Car car=new Car();car.color="黑色";car.brand="瑪莎拉蒂";car.num=4;car.run();//new就是一個新的對象Car car2=new Car();car2.run();//匿名對象 沒有名字對象 只能使用一次,看到new就是一個新的對象new Car().run();new Car().color="";//引用數(shù)據(jù)類型的成員變量值為null//Car car3=null; 引用數(shù)據(jù)類型變量的聲明,對象指向為nullcar3.run(); //NullPointerException 使用某個對象的某個功能,但是這個對象沒有真實存在,指向 為null,所以會發(fā)生空指針} }3)對象之間的相互調(diào)用
①將對象引用作為方法的方法列表:
實例:
首先我們創(chuàng)建一個秘書類和一個國家類:
public class Country08{ //國家名字public String name;//酒店名字public String hotelName; }&
/*秘書類:屬性:名字功能:訂酒店 */ public class Secretary{ //名字public String name;//訂酒店 可通過傳入實參來實現(xiàn)功能/*public void bookHotel(String countryName,String hotelName){System.out.println(name+"正在為您預(yù)定"+countryName+"的"+hotelName+"...");}*///也可以通過將對象作為引用數(shù)據(jù)類型的參數(shù),傳入bookHotel方法的方法列表,在該方法中直接使用該對象的屬性public void bookHotel(Country08 country){ //country=0x00a;System.out.println(name+"正在為您預(yù)定"+country.name+"的"+country.hotelName+"...");} }我們來測試這兩個類:
public class TravelTest10{ public static void main(String[] args){//創(chuàng)建一個秘書類Secretary sec=new Secretary();// 賦值sec.name="胡歌"; //創(chuàng)建國家對象Country08 country=new Country08();country.name="迪拜";country.hotelName="帆船酒店";//將country作為引用數(shù)據(jù)類型傳入bookHotel()方法的參數(shù)列表中,可直接使用country對象的屬性sec.bookHotel(country);} }②將對象引用作為方法的返回值:
實例:
新建蛋糕類和糕點師類:
/** 蛋糕類:* 尺寸* 形狀* 口味* ...* * 展示細(xì)節(jié)*/ public class Cake {public int size;public String shape;public String taste;//空構(gòu)造public Cake() {// TODO Auto-generated constructor stub}//帶參構(gòu)造public Cake(int cakeSize, String cakeShape, String cakeTaste) {super();this.size = cakeSize;this.shape = cakeShape;this.taste = cakeTaste;}//功能:展示蛋糕細(xì)節(jié)public void info(){System.out.println(size+"->"+shape+"->"+taste);} } //------------------------------------------------------------------------ /** 蛋糕師:* 名字* 制作蛋糕*/ public class CakePeople {public String name;//空構(gòu)造public CakePeople() {// TODO Auto-generated constructor stub}//帶參構(gòu)造public CakePeople(String cakerName) {name=cakerName;}//功能:制作蛋糕//返回值:需要返回一個蛋糕 參數(shù):int size, String shape, String tastepublic Cake make(int size, String shape, String taste){//new一個cake類對象,并利用其構(gòu)造器,將make()方法中的參數(shù)傳入,制作蛋糕Cake cake=new Cake(size,shape,taste);System.out.println("蛋糕師正在制作蛋糕");//返回一個蛋糕引用類型return cake;} }測試:
public class Test {public static void main(String[] args) {//測試蛋糕師制作蛋糕//創(chuàng)建一個蛋糕師對象CakePeople people=new CakePeople("小麗");/*利用蛋糕師對象調(diào)用其成員方法make(12, "心形", "巧克力味")制作一個蛋糕,make方法返回的是一個蛋 糕類型,利用Cake cake引用來接收一個制作好的蛋糕類型即new Cake(12, "心形", "巧克力味");再利用cake調(diào)用其成員方法info()來展示蛋糕*/Cake cake=people.make(12, "心形", "巧克力味");cake.info();③將對象引用作為類的成員屬性:
實例:
新建學(xué)校類和學(xué)生類:
/** 學(xué)校類*/ public class School {public String name;public String location;public School() {// TODO Auto-generated constructor stub}public School(String schoolName,String schoolLoc) {name=schoolName;location=schoolLoc;} } //------------------------------------------------------------------------ /** 屬性 :姓名,所在學(xué)校名字* 學(xué)生在學(xué)校里,想知道在什么學(xué)校,學(xué)校的位置等詳細(xì)的學(xué)校信息,* 就不適合將自定義類型作為方法的參數(shù)來傳參(因為會用到很多學(xué)校的信息,寫不過來)* 因此將學(xué)校這個自定義類型作為學(xué)生的成員屬性,學(xué)生類中的所有功能都能調(diào)用學(xué)校這* 個成員屬性,學(xué)校類又能使用自己的成員方法和屬性,非常靈活*/ public class Student {public String name;//public String schoolName;//自定義類型 不僅可以作方法的參數(shù),返回值,還可以作類的成員屬性public School school; //當(dāng)前這個類中的所有方法中都能使用的public Student() {// TODO Auto-generated constructor stub}public Student(String studentName,School schoolName) {name=studentName;school=schoolName;}//學(xué)校類使用自己的成員屬性或功能public void info(){System.out.println(name+"正在位于"+school.location+"的"+school.name+"學(xué)習(xí)java....");} }測試:
public class Test {public static void main(String[] args) {//測試學(xué)生類//利用構(gòu)造器new一個學(xué)校對象,給學(xué)校賦值信息School school=new School("北京大學(xué)","地址1");School school2=new School("北京大學(xué)","地址2");//new一個學(xué)生對象Student stu=new Student();stu.name="小王";//將學(xué)校類型賦值給學(xué)生類對象的成員屬性//stu.schoolName="北京大學(xué)";stu.school=school;stu.info();//或直接利用構(gòu)造器,在new學(xué)生對象的時候,就對學(xué)生對象的成員屬性學(xué)校初始化信息Student stu2=new Student("小麗",school);stu2.info();Student stu3=new Student("小明",school2);stu3.info();//這兩個學(xué)生是在一個學(xué)校么?//==比較對象的地址,stu3的學(xué)校對象時新new的,和stu的學(xué)校對象地址不同,所以不相同System.out.println(stu.school==stu2.school);System.out.println(stu.school==stu3.school);} }四.構(gòu)造器:
new創(chuàng)建對象會執(zhí)行的步驟:
? 1.在堆中為對象開辟空間,當(dāng)前類的成員屬性會跟隨對象進入到堆內(nèi)存并附默認(rèn)值
? 2.調(diào)用構(gòu)造器為對象初始化信息(一般為成員屬性第一次賦值)
? 3.將對象的地址返回給引用
構(gòu)造器|構(gòu)造方法|構(gòu)造函數(shù):
作用:
? 初始化對象信息
定義:
? 修飾符 類名([參數(shù)]){
? …
? }
? 1.沒有返回值類型,沒有void
? 2.可以根據(jù)需求存在return,提前結(jié)束方法
? 3.構(gòu)造器不能和static,abstract,final一起使用
調(diào)用:
? 跟隨new使用,new其中的一步
1.如果沒有顯示構(gòu)造器,編譯器會隱式為你提供一個空構(gòu)造
2.如果存在自定義構(gòu)造器,編譯器不會再為你提供任何構(gòu)造器, 包括空構(gòu)造
3.定義多個構(gòu)造器,參數(shù)列表不同,構(gòu)成構(gòu)造器的重載,調(diào)用根據(jù)()中的實參匹配不同的構(gòu)造器
4.構(gòu)造器的修飾符可以是private,私有的,只能在當(dāng)前類中使用這個構(gòu)造器
根據(jù)不同的需求定義不同的構(gòu)造器,一般都會存在至少一個空構(gòu)造
實例:
class Dog{public String name;public String type;//默認(rèn)提供空構(gòu)造private Dog() { //只能再當(dāng)前Dog類中才能使用這個構(gòu)造器為對象初始化信息System.out.println("我是空構(gòu)造.....");}//帶參構(gòu)造器public Dog(String dogName){name=dogName; //為成員屬性name賦值}public Dog(String dogName,String dogType){name=dogName;type=dogType;}//普通的方法 public void Dog(){ //方法名不符合標(biāo)識符的命名規(guī)范System.out.println(name+"---->"+type);Dog dog=new Dog();}//功能為看家public void lookHome(){System.out.println(name+"正在看家...");}}五.this關(guān)鍵字:
this 是自身的一個對象,代表對象本身,可以理解為:指向?qū)ο蟊旧淼囊粋€指針。
this 的用法在 Java 中大體可以分為3種:
1)普通直接引用:
? this 相當(dāng)于是指向當(dāng)前對象本身,代表當(dāng)前對象.
2)區(qū)分同名變量問題(成員變量與局部變量,參數(shù)之間同名問題):
? this使用在構(gòu)造器中,指代當(dāng)前創(chuàng)建的對象
? this使用在成員方法中,this指代當(dāng)前調(diào)用成員方法的對象
? 默認(rèn)發(fā)生就近原則
? 不存在同名變量|參數(shù)問題,變量就是指代成員,前面默認(rèn)省略this.
3)在構(gòu)造器的首行調(diào)用其他構(gòu)造器:
this(參數(shù))--------------->調(diào)用匹配不同參數(shù)的構(gòu)造器
注意:
? 1.調(diào)用構(gòu)造器的時候this必須存在第一行才行
? 2.構(gòu)造器之間不能相互調(diào)用
? 3.this不能使用在static修飾的內(nèi)容中
實例:
//測試類 public class ThisDemo {public static void main(String[] args) {Person p=new Person("張三",18,true);p.info();//打印 張三+-->18-->truePerson p2=new Person("李四");Person p3=new Person("王五");p2.info();//打印 李四+-->+0+-->falsep3.info();//打印 王五+-->+0+-->falsep.test(222);//this.age指當(dāng)前創(chuàng)建對象的成員變量為18p2.test(111);//this.age指當(dāng)前創(chuàng)建對象的成員變量為0} }//創(chuàng)建一個人類型 class Person{//成員屬性public String name;public int age;public boolean gender; //true->女 false->男//空構(gòu)造public Person() {// TODO Auto-generated constructor stub}//帶參構(gòu)造,this指代當(dāng)前新創(chuàng)建的對象public Person(String name) {this.name=name;}//兩個參數(shù)的構(gòu)造器,給人的姓名\年齡賦值,this指代當(dāng)前新創(chuàng)建的對象public Person(String name,int age) {this.name=name;this.age=age;}//三個參數(shù)的構(gòu)造器public Person(String name,int age,boolean gender) {//上一個構(gòu)造器就是給name,age賦值的this(name,age); //調(diào)用本類中的其他構(gòu)造器 如果實參位置是變量,傳遞的就是變量的值this.gender=gender;}//打印所有成員屬性的值public void info(){System.out.println(name+"-->"+age+"-->"+gender);}public void test(int age){System.out.println(this.age+","+gender); //默認(rèn)就近原則} }六.塊block:
塊block: { }->作用域
-
局部代碼塊|普通語句塊-----------------> { }定義在方法中 執(zhí)行時機:調(diào)用方法
-
構(gòu)造塊 -----------------> { }定義在類中方法外 執(zhí)行時機:new
-
靜態(tài)塊 ----------------->static{ }定義在類中方法外 執(zhí)行時機:在類第一次加載以后執(zhí)行一次
-
同步塊
-
構(gòu)造塊先于構(gòu)造器的代碼執(zhí)行,如果存在多個構(gòu)造塊,從上到下以此執(zhí)行
-
靜態(tài)塊先于主方法執(zhí)行,如果存在多個靜態(tài)塊,從上到下依次執(zhí)行
-
構(gòu)造塊在編譯的時候,就會被編譯到最先執(zhí)行的構(gòu)造器中代碼的最上方(其實構(gòu)造塊并不是單獨優(yōu)先于構(gòu)造器執(zhí)行,而是在構(gòu)造器執(zhí)行代碼時,在構(gòu)造器要執(zhí)行的代碼之上執(zhí)行.)
執(zhí)行順序:
static->main->構(gòu)造塊->構(gòu)造器
實例:
public class BlockDemo {//如果存在靜態(tài)塊,靜態(tài)變量,從上到下依次執(zhí)行static int a=10;static{System.out.println(a);}int b=5;static{System.out.println("我是靜態(tài)塊1"+a);}static{System.out.println("我是靜態(tài)塊2");}public BlockDemo01() {System.out.println("我是構(gòu)造器");}//構(gòu)造塊{System.out.println("我是構(gòu)造塊1");System.out.println(a);System.out.println(b);}{System.out.println("我是構(gòu)造塊2");}{System.out.println("我是構(gòu)造塊3");}//測試:public static void main(String[] args) {System.out.println("main");int a=15; //作用域在變量聲明開始,到離我最近的,包裹你的{}的}為止//同一個作用域之內(nèi)變量不能重名,使用就近原則使用//局部代碼塊{int b=5; //作用域就在代碼塊中System.out.println(a);}System.out.println("-------"+BlockDemo01.a);BlockDemo01 bd=new BlockDemo01();System.out.println(bd.a);//System.out.println(b); 無法使用} }注意:
構(gòu)造塊在編譯的時候,就會被編譯到最先執(zhí)行的構(gòu)造器中代碼的最上方(其實構(gòu)造塊并不是單獨優(yōu)先于構(gòu)造器執(zhí)行,而是在構(gòu)造器執(zhí)行代碼時,在構(gòu)造器要執(zhí)行的代碼之上執(zhí)行.)
實例:
我們來看他們的執(zhí)行順序
public class BlockTest {public static int a = 0;{a = 10;System.out.println("3、非靜態(tài)代碼塊執(zhí)行a=" + a); // 10} static {a = 6;System.out.println("1、靜態(tài)代碼塊執(zhí)行a=" + a); //6}public BlockTest() { this(a); // 最先執(zhí)行,如果構(gòu)造塊放在this()前面,語法不通過,因為this必須在首行System.out.println("6、"+a); // 10System.out.println("7、無參構(gòu)造方法執(zhí)行a=" + a); //10}public BlockTest(int n) { System.out.println("4、"+n); // 6 System.out.println("5、"+a); // 10} public static void main(String[] args) {System.out.println("2、main"); //main主方法BlockTest tsc = new BlockTest(); } }
七.static關(guān)鍵字:
static關(guān)鍵字為靜態(tài)的成員修飾符
類變量|靜態(tài)變量: static修飾變量,只能成員變量,不能修飾局部變量
類 方法|靜態(tài)方法: static修飾的方法
靜態(tài)的內(nèi)容的使用方式:
-
類名.方法名([參數(shù)列表]);
-
類名.屬性名;
-
對象.方法名字([參數(shù)列表]);
-
對象.屬性名;
被static修飾的靜態(tài)的內(nèi)容是屬于類的,可以通過類使用,可以通過對象去使用
成員的內(nèi)容是屬于對象的,成員變量,成員方法只能通過對象調(diào)用
靜態(tài)的內(nèi)容中,只能直接使用靜態(tài)的內(nèi)容,但成員內(nèi)容需要通過對象使用
非靜態(tài)的內(nèi)容中,可以直接使用靜態(tài)的,也可以直接使用非靜態(tài)的內(nèi)容
只在類第一次加載的時候初始化一次,靜態(tài)的內(nèi)容是獨一份的,所有的對象共享一個類中的靜態(tài)內(nèi)容
實例:
public class StaticDemo01 {//靜態(tài)變量static int age=5;//成員變量int id=10;//靜態(tài)的方法public static void main(String[] args) {//局部變量不能使用static修飾//int a=5;System.out.println(age); //當(dāng)前類中,可以省略類名StaticDemo01 demo=new StaticDemo01();System.out.println(demo.id); //10System.out.println(demo.age); System.out.println(StaticDemo01.age); //5//System.out.println(StaticDemo01.id); System.out.println(demo);demo.change(); //6 11System.out.println(demo.id); // 11System.out.println(StaticDemo01.age); //6demo.change(); // 7 12System.out.println(demo.id); // 12System.out.println(demo.age); // 7 StaticDemo01.change2(); //8 -> 11 System.out.println(demo.id); // 12System.out.println(demo.age); // 8 demo.change2(); // 9-> 11 System.out.println(demo.id); // 12System.out.println(demo.age); // 9}/** 改變屬性值*/public void change(){age++; //靜態(tài)的id++; //成員的System.out.println(age+"-->"+id); System.out.println("this:"+this);}public static void change2(){age++; //靜態(tài)的StaticDemo01 demo=new StaticDemo01();demo.id++; //成員的System.out.println(age+"-->"+demo.id); } }八.導(dǎo)包
注意: 不要定義與 jdk 相同的包,相同的類, 否則會引起很多你覺得莫名其妙的問題
import 導(dǎo)包 執(zhí)行包名+類名
模糊匹配,導(dǎo)入一個包下的所有類,降低編譯效率,不會降低運行效率? 靜態(tài)導(dǎo)入:導(dǎo)入靜態(tài)的內(nèi)容(屬性|方法)(如 :import static java.lang.Math.PI;)
? 調(diào)用該類靜態(tài)方法時,直接調(diào)用
? 需要注意: 當(dāng)類重名時,需要指定具體的包名。
? 當(dāng)方法重名時,需要指定具體的類或?qū)ο竺?/p> import java.util.*;//模糊匹配 import static java.lang.Math.PI;//靜態(tài)導(dǎo)入屬性 import static java.lang.Math.sqrt;//靜態(tài)導(dǎo)入方法 public class ImportDemo {public static void main(String[] args) {java.util.Scanner sc=new java.util.Scanner(System.in);Random ran=new Random();System.out.println(PI);//調(diào)用該類靜態(tài)屬性時,直接調(diào)用System.out.println(sqrt(4));//調(diào)用該類靜態(tài)方法時,直接調(diào)用} }
九.Java的垃圾回收機制
垃圾回收機制:
? System.gc() 通知垃圾回收機制來回收垃圾
? 是否回收,什么時候回收手動控制不了
finalize()方法 如果回收垃圾,第一步會調(diào)用這個方法
一定會調(diào)用finalize()方法的情況:
? 1.匿名對象(無引用的對象)
? 2.對象無引用狀態(tài)
十.Java 封裝
在面向?qū)ο蟪淌皆O(shè)計方法中,封裝(英語:Encapsulation)是指一種隱藏內(nèi)部的實現(xiàn)細(xì)節(jié),對外提供公共的訪問方式的方法。
封裝可以被認(rèn)為是一個保護屏障,防止該類的代碼和數(shù)據(jù)被外部類定義的代碼隨機訪問。
要訪問該類的代碼和數(shù)據(jù),必須通過嚴(yán)格的接口控制。
封裝最主要的功能在于我們能修改自己的實現(xiàn)代碼,而不用修改那些調(diào)用我們代碼的程序片段。
適當(dāng)?shù)姆庋b可以讓程式碼更容易理解與維護,也加強了程式碼的安全性。
封裝的優(yōu)點:
-
良好的封裝能夠減少耦合。
-
類內(nèi)部的結(jié)構(gòu)可以自由修改。
-
可以對成員變量進行更精確的控制。
-
隱藏信息,實現(xiàn)細(xì)節(jié)。
-
修改屬性的可見性來限制對屬性的訪問(一般限制為private),將屬性設(shè)置為私有的,只能本類才能訪問,其他類都訪問不了,如此就對信息進行了隱藏。
-
對每個值屬性提供對外的公共方法訪問,也就是創(chuàng)建一對賦取值方法,用于對私有屬性的訪問。
-
super:指代父類對象
-
super使用在構(gòu)造器的首行,調(diào)用父類的某個構(gòu)造器
super(參數(shù)列表)使用在首行默認(rèn)在子類構(gòu)造器的首行會調(diào)用父類空構(gòu)造,如果顯示定義super(參數(shù)),不會再默認(rèn)調(diào)用父類空構(gòu)造了需求:當(dāng)創(chuàng)建父類對象時,需要使用父類中的其他構(gòu)造器,通過super(參數(shù))顯示定義調(diào)用哪一個,否則默認(rèn)調(diào) 用空構(gòu)造注意:this和super不能同時存在與構(gòu)造器的首行調(diào)用構(gòu)造器,除了顯示定義this(),隱式調(diào)用super(),僅僅調(diào)用父類空構(gòu)造 -
區(qū)分同名問題
如果存在子父類中成員同名問題,默認(rèn)調(diào)用子類的,就近原則如果不存在同名,默認(rèn)調(diào)用父類,相當(dāng)于省略了super.this和super都不能使用在static內(nèi)容中,因為靜態(tài)方法直接被類使用,可以不創(chuàng)建對象調(diào)用,所以不一定有父類和子類對象,因此不能使用創(chuàng)建對象:先父類后子類(默認(rèn)創(chuàng)建的父類對象在子類的內(nèi)存空間中,外部無權(quán)使用默認(rèn)創(chuàng)建的在子類內(nèi)存中的父類對象,如果需要使用父類對象,自己手動創(chuàng)建父類對象)
public class SuperDemo {public static void main(String[] args) {Zi zi=new Zi("heihei",14);System.out.println(zi);zi.info();} }class Fu{String name="呵呵";int age;public Fu() {System.out.println("我是父類空構(gòu)造");}public Fu(String name,int age) {this.name=name;this.age=age;System.out.println("我是父類帶參構(gòu)造");}public void test(){System.out.println("fU...........");}} class Zi extends Fu{int a;String name="哈哈";public Zi() {//super();super();System.out.println("我是子類空構(gòu)造");}//從父類中繼承的某些成員屬性賦值public Zi(String name,int age) {/*this.name=name;this.age=age;*///super(name,age); this();System.out.println("我是子類帶參構(gòu)造");}public void info(){//String name="李四";System.out.println(this.name+"-"+super.name+"->"+this.age);System.out.println(this);//System.out.println(super);super.test();}public void test(){System.out.println("ZI...........");}public static void haha(){//System.out.println(super.name);} }十三.權(quán)限修飾符
權(quán)限修飾符: 內(nèi)容被訪問的權(quán)限
? 本類 同包類 不同包子類 不同包其他類
private Y
default Y Y
protected Y Y Y
public Y Y Y Y
權(quán)限修飾符為成員修飾符,不能修飾局部
能夠修飾類的權(quán)限修飾符:public|default(隱式定義)
父類中私有的內(nèi)容是不能繼承的
protected使用途徑:
? 1.同包類
? 2.不同包子類繼承關(guān)系使用
public class ModifierDemo {public static void main(String[] args) {new Demo().test();Demo d=new Demo();System.out.println(d.defaultMo);System.out.println(d.protectedMo);System.out.println(d.publicMo);//System.out.println(d.privateMo);//d.privateMo報錯,說明私有只能在本類中使用} }實例:
父類:
public class Demo {public String publicMo="哈哈";int defaultMo=101;protected boolean protectedMo=false;private double privateMo=111.22;public void test(){System.out.println(publicMo);System.out.println(defaultMo);System.out.println(protectedMo);System.out.println(privateMo);} }class Son extends Demo{void demo(){//System.out.println(privateMo);} }不同包子類
public class SonTest extends Demo{public void haha(){Demo d=new Demo();//System.out.println(d.defaultMo);//System.out.println(d.protectedMo); 非繼承關(guān)系訪問,直接訪問權(quán)限修飾符的權(quán)限System.out.println(protectedMo); //通過繼承關(guān)系訪問 子類一旦繼承父類,可以直接使 用父類中的內(nèi)容//protected修飾的成員在子類中只能通過繼承關(guān)系訪問,通過new父類對象調(diào)用不可訪問System.out.println(d.publicMo); } }不同包其他類
public class Test {public static void main(String[] args) {SonTest son=new SonTest();//System.out.println(son.protectedMo); 因為這個protectedMo是Demo類中定義的,是 受保護的,當(dāng)前使用的類Test,和Demo類不構(gòu)成繼承關(guān)系,是不同包的其他類,無權(quán)使用}public void haha(){Demo d=new Demo();//System.out.println(d.defaultMo);//System.out.println(d.protectedMo);System.out.println(d.publicMo);} }十四.Java方法的重寫Override
重寫是子類對父類的允許訪問的方法的實現(xiàn)過程進行重新編寫, 返回值和形參都不能改變。即外殼不變,核心重寫!
重寫的好處在于子類可以根據(jù)需要,定義特定于自己的行為。 也就是說子類能夠根據(jù)需要實現(xiàn)父類的方法。
重寫方法不能拋出新的檢查異常或者比被重寫方法申明更加寬泛的異常。例如: 父類的一個方法申明了一個檢查異常 IOException,但是在重寫這個方法的時候不能拋出 Exception 異常,因為 Exception 是 IOException 的父類,只能拋出 IOException 的子類異常。
在面向?qū)ο笤瓌t里,重寫意味著可以重寫任何現(xiàn)有方法。
重寫:
- 1.不同的類
- 2.繼承關(guān)系|實現(xiàn)
- 3.方法簽名相同(方法名+參數(shù)列表)
測試一個方法是否為標(biāo)準(zhǔn)的重寫方法:
- 1.重寫方法左邊會出現(xiàn)三角形
- 2.@Override 強制檢測是否為重寫方法
為什么要使用重寫?
? 父類的功能你也有,但是實現(xiàn)體不一樣,就可以對這個功能在子類中進行重寫
調(diào)用:
? 如果子類中有重寫方法,會調(diào)用子類的,否則調(diào)用父類的–就近原則
要求:
? == :方法簽名完全相同
? <= :返回值類型如果是基本數(shù)據(jù)類型必須相等,如果是引用數(shù)據(jù)類型,子類<=父類
? = :權(quán)限修飾符 子類>=父類
不能被重寫的方法:
? 1.被private修飾的方法不能被重寫
public class OverrideDemo {public static void main(String[] args) {new SiCong().words();new SiCong().hehe();} }class JianLin{public JianLin words(){System.out.println("先定一個小目標(biāo),掙他一個億...");return null;}public static void hehe(){System.out.println("hhhhhhhhhhhhhhh");} }class SiCong extends JianLin{//重寫: 父類的功能你也有,但是實現(xiàn)體不一樣,就可以對這個功能在子類中進行重寫@Overridepublic JianLin words(){System.out.println("我不在乎的我的朋友有沒有錢,反正都沒我有錢...");return null;}//不是重寫方法public static void hehe(){System.out.println("hhhhhhhhhhhhhhh");} }
? 2.被final修飾的方法不能被重寫(final修飾的內(nèi)容不能再被改寫)
? 3.被static修飾的方法不能被重寫(被static修飾的方法能被繼承,但不能被重寫)
注意:如果子類中定義的方法名與父類靜態(tài)方法的方法名相同,子類這個方法也要被static修飾,但是卻不是重寫方法十五.final關(guān)鍵字
final關(guān)鍵字:
? 1.被final修飾的變量為常量,不能修改
? 2.被final修飾的方法不能被重寫
? 3.被final修飾的類不能被繼承,太監(jiān)類
十六.Object類
Object類為所有的類的父類
java中的類肯定會直接或者間接的繼承自O(shè)bject
toString() 把對字符串的形式顯示
? 當(dāng)打印對象的時候,默認(rèn)會調(diào)用toString方法
? 默認(rèn)調(diào)用Object類型的toString方法,打印對象的地址
? 如果想要獲取所有屬性值,在子類中重寫toString()方法,自定義返回值的內(nèi)容
equals() 比較對象是否相等
? == 和 equals的區(qū)別:
? ==比較對象的地址
? equals 如果使用Object類中的equals方法實現(xiàn),比較的還是對象的地址
? 通過方法的重寫,在子類中重寫equals方法,自定義比較規(guī)則,實現(xiàn)比較對象的內(nèi)容非地址
? 因為:比較對象的內(nèi)容,一般認(rèn)為所有成員屬性的值|某些成員屬性值相同,就是一個對象
public class ObjectDemo extends Object {public static void main(String[] args) {ObjectDemo o=new ObjectDemo();System.out.println(o);System.out.println(o.toString());Person p1=new Person(01,"沈達(dá)",20);Person p2=new Person(01,"哈哈",25); System.out.println(p1);//打印一個對象,其實想要獲取對象成員屬性值,但是默認(rèn)調(diào)用的toString方法,會得到對象的地址System.out.println(p2);System.out.println(p1==p2);System.out.println(p1.equals(p2));//System.out.println("HAHA".equals(p1));} }class Person{int id;String name;int age;public Person() {// TODO Auto-generated constructor stub}public Person(int id,String name, int age) {this.id=id;this.name = name;this.age = age;}//對toString方法進行重寫@Overridepublic String toString() {// TODO Auto-generated method stubreturn name+"-->"+age;}//對equals方法進行重寫//如果:id相同就就是一個人,比較結(jié)果英文返回true@Overridepublic boolean equals(Object obj) {//增強程序的健壯性 //比較兩個對象地址是否相同,地址相同為一個對象if(this==obj){return true;}//判斷obj是否是Person類型,如果不是,則返回false,如果是,則比較id是否相同if(obj instanceof Person){return this.id==((Person)obj).id;}return false;} }十七.Java 多態(tài)
多態(tài):一種事物的多種形態(tài)|多種表現(xiàn)形式
多態(tài)的前提:
? 類的繼承
? 接口的實現(xiàn)
多態(tài)的體現(xiàn)|表現(xiàn)形式:
? 父類的引用指向子類對象
多態(tài)的使用:
? 父類的引用在調(diào)用方法,調(diào)用子類中重寫的方法
注意:
? 父類引用對子類新增功能不可見(可強轉(zhuǎn))
? 如果子類中沒有重寫方法,多態(tài)沒有意義
多態(tài)使用成員:
? 成員變量:
? 編譯 運行看父類|左邊|類型
(只看父類中的成員變量,與子類無關(guān),因為多態(tài)的使用是調(diào)用子類重寫的方法)
? 成員方法:
? 編譯看父類,運行看子類(編譯看類型,運行找對象 | 編譯看左邊,運行看右邊)
(看有無調(diào)用的成員方法,若有則運行時先看子類有無重寫,若沒有重寫則調(diào)用父類成員方法)
public class PhyDemo01 {public static void main(String[] args) {//多態(tài)Person s=new Student();//Student s=new Student();//s.sleep();//s.study();s.test();System.out.println(s.name);//打印的是父類成員"王健林",因為多態(tài)的使用僅僅是調(diào)用子類重寫 的方法} }class Animal{} class Person{static String name="王健林";public void sleep(){System.out.println("睡覺");}public static void test(){System.out.println("hhhhhhhhhhhhh");} }class Student extends Person{String name="王思聰";//重寫sleep方法public void sleep(){System.out.println("邊敲代碼邊睡覺...");}//新增功能public void study(){System.out.println("學(xué)習(xí)java..");}//靜態(tài)方法不是重寫方法public static void test1(){System.out.println("hehehehehehehe");} }十八.Java 多態(tài)的轉(zhuǎn)型問題
轉(zhuǎn)型: java是一門強類型的語言
基本數(shù)據(jù)類型: 自動類型提升 強制類型轉(zhuǎn)換
引用數(shù)據(jù)類型: 向上轉(zhuǎn)型(自動)(小–>大) 向下轉(zhuǎn)型(強轉(zhuǎn))(大–>小)
小范圍類型–>子類
大范圍類型–>父類
孔子裝爹案例:
class 孔子爹{void teach(){做生意};}
class 孔子{void teach(){論語}; void play(){吃雞};}
有一個來請孔子爹教學(xué),不巧孔子爹外出了,孔子化妝裝成孔子爹的樣子,去授課
//向上轉(zhuǎn)型 化妝
KongZiDie k=new KongZi(); (多態(tài))
k.teach(); //論語(重寫父類KongZiDie中的teach方法)
與學(xué)生一起玩游戲,但是孔子爹不會游戲,只有孔子會,需要卸妝變成孔子類型調(diào)用play功能
//向下轉(zhuǎn)型 卸妝
KongZi kongzi=(KongZi)k;(想要調(diào)用子類新增方法play,將K向下轉(zhuǎn)型成子類KongZi類型,再用子類KongZi類型去接收)
kongzi.play();(才可以調(diào)用子類新增的方法)
向下轉(zhuǎn)型:當(dāng)需要調(diào)用子類獨有的功能,需要向下轉(zhuǎn)型
ClassCastException 類型轉(zhuǎn)換異常
避免向下轉(zhuǎn)型轉(zhuǎn)型錯誤,出現(xiàn)類型轉(zhuǎn)換異常的問題,可用 instanceof(如果不是同種類型的對象或子類對象,就強轉(zhuǎn)不了)
使用方法:
引用 instanceof 類型
作用:判斷前面的引用是否為后面類型的對象或子類的對象
如果是,返回true,如果不是,返回false
編譯只檢查引用的類型與后面的類型是否在一條繼承鏈上,如果是就語法沒有錯誤(編譯不報錯)
面向?qū)ο?
? 封裝: 隱藏內(nèi)部的實現(xiàn)細(xì)節(jié),對外提供公共的訪問方式
? 繼承: 子類一旦繼承父類,就自動擁有父類的內(nèi)容+子類的擴展
? 多態(tài): 結(jié)合繼承,和方法的重寫,封裝可以提高代碼的復(fù)用性和擴展性
實現(xiàn)Java封裝的步驟:
實例:
/* 標(biāo)準(zhǔn)的javabean類要求:* 1.類公共的被public修飾* 2.屬性私有* 3.公共的設(shè)置器和訪問器* 4.至少有一個空構(gòu)造*/public class Person {private String name;private int age;//空構(gòu)造public Person() {// TODO Auto-generated constructor stub}//帶參構(gòu)造public Person(String name, int age) {super();this.name = name;this.age = age;}//age私有的屬性設(shè)置器 返回值:不用 參數(shù):需要 int//可以在屬性設(shè)置器中對傳入的設(shè)置器的參數(shù)作篩選public void setAge(int age){if(age>=0 && age<150){this.age=age;}else{System.out.println("年齡不合法...");this.age=18;}}//age屬性的訪問器 getter 返回值:返回age的值 int 參數(shù):不需要public int getAge(){return this.age;}//成員方法public void info(){int a=5;System.out.println(this.name+"-->"+age);} }十一.Java 繼承
繼承的概念:
繼承是java面向?qū)ο缶幊碳夹g(shù)的一塊基石,因為它允許創(chuàng)建分等級層次的類。
繼承就是子類繼承父類的特征和行為,使得子類對象(實例)具有父類的實例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為。
使用繼承的目的:
? 為了提高代碼的復(fù)用性
如何使用繼承:
? 定義子父類,使用extends關(guān)鍵字 子類 extends 父類
? 定義父類:抽取一系列子類的功能,定義為父類
? 子類一旦繼承父類,就能夠使用父類中的內(nèi)容
? 子類可以定義自己獨有的內(nèi)容,擴展父類的功能
? java中類只能單繼承,可以多實現(xiàn)
繼承: 延續(xù)+擴展
單繼承的優(yōu)點:
使用簡單
單繼承的缺點:
局限性大,不便于后期維護
開閉原則:面向?qū)ο蟮脑O(shè)計原則之一
對修改關(guān)閉,對擴展開放
十二.super關(guān)鍵字
super 和 this
十九.抽象類
抽象類 : 被abstract修飾的類
抽象方法 : 被abstract修飾的方法
抽象方法沒有方法體且必須存在抽象類中
注意:
1.抽象類不能實例化
2.抽象方法必須存在于抽象類中
3.抽象類中可以存在抽象方法,可以存在具體方法(有方法體的方法)
4.通過子類使用抽象類:
? 具體子類:重寫抽象父類中的所有抽象方法+按需新增
? 抽象子類:按需重寫抽象方法+按需新增
5.一個抽象方法如果已經(jīng)被重寫過,再次繼承時就可以不需要再次重寫
6.抽象方法必須被重寫
7.abstract不能和static, final,private,native一起使用
實例:
定義開發(fā)部:
? Develop開發(fā)部 功能:工作
? Java工程師 功能:工作
? web工程師 功能:工作
抽象父類:
public abstract class Develop {//不知道怎么定義方法體,就不寫,沒有方法體的方法只能為抽象方法public abstract void work();public abstract void sleep();public void haha(){System.out.println("哈哈一笑");} }具體子類:
public class Java extends Develop{@Overridepublic void work() {System.out.println("做服務(wù)器端開發(fā)...");}@Overridepublic void sleep() {System.out.println("站著睡覺...");}public void hehe() {System.out.println("聊天止于呵呵");}}抽象子類:
public abstract class Web extends Develop{@Overridepublic void work(){System.out.println("邊吃東西做瀏覽器端開發(fā)...");};@Overridepublic abstract void sleep();public void smile() {System.out.println("聊天止于微笑");} }子類繼承Web抽象子類:
public class ExtendsWeb extends Web{@Overridepublic void sleep() {}@Overridepublic void work(){System.out.println("做瀏覽器端開發(fā)...");} }二十.接口
接口(英文:Interface),在JAVA編程語言中是一個抽象類型,是抽象方法的集合,接口通常以interface來聲明。一個類通過繼承接口的方式,從而來繼承接口的抽象方法。
接口并不是類,編寫接口的方式和類很相似,但是它們屬于不同的概念。類描述對象的屬性和方法。接口則包含類要實現(xiàn)的方法(也可將其視為特殊的抽象類)。
在1.7及之前:
接口能定義的內(nèi)容: 靜態(tài)的公共的常量 + 公共的抽象的方法
常量:
public static final默認(rèn)修飾符,可以選擇性的省略
方法:
public abstract 默認(rèn)修飾符,可以選擇性的省略
1.8及之后版本:
新增: 1.靜態(tài)方法:接口名字. 使用
? 2.默認(rèn)方法:實現(xiàn)類的對象使用
靜態(tài)的公共的常量 + 公共的抽象的方法 + 靜態(tài)方法 + 默認(rèn)方法
注意:
? 1.類的繼承,接口需要實現(xiàn)
? 2.抽象方法必須被重寫
? 3.使用接口中的內(nèi)容:接口需要實現(xiàn)implements,類要使用extends繼承
具體的實現(xiàn)類: 重寫接口中的所有抽象方法+按需新增
抽象的實現(xiàn)類: 按需重寫抽象方法+按需新增
? 4.單繼承,一個類只能繼承一個類,接口可以多實現(xiàn),實現(xiàn)了接口,就擁有了接口中定義的功能
? 5.一個類及繼承父類又實現(xiàn)接口,應(yīng)先繼承后實現(xiàn)
? 6.避免實現(xiàn)的多個接口中定義了相同的功能
7.接口可以多繼承其他接口,不能是實現(xiàn)接口的(實現(xiàn):對抽象方法方法體的實現(xiàn))
? 8.接口不能實例化
接口的優(yōu)點:
? 避免單繼承的局限性 (推薦使用接口)
? 提高代碼的復(fù)用性
? 解耦:高內(nèi)聚低耦合
? 定義規(guī)范
public abstract class InterfaceDemo implements MyIn{public static void main(String[] args) {System.out.println(MyIn.A);//new InterfaceDemo().haha();MyIn.heihei();new Demo().houhou();}@Overridepublic int haha() {System.out.println("我是重寫的抽象方法");return 0;}//public abstract void hehe(); }class Demo implements MyIn{@Overridepublic int haha() {// TODO Auto-generated method stubreturn 0;}@Overridepublic void hehe() {// TODO Auto-generated method stub}}//自定義的父類接口 interface MyIn{//公共的靜態(tài)的常量,選擇性省略public static finalint A=5;//定義了有這個功能,選擇性省略public abstract int haha();void hehe();//靜態(tài)方法staticpublic static void heihei(){System.out.println("heihei..........");}//默認(rèn)方法defaultpublic default void houhou(){System.out.println("嚶嚶怪...");} } //-------------------------------------------------------------- interface A{void a(); } interface B{void b(); }//一個接口繼承其他的接口,接口可多繼承其他多個接口,但接口不能實現(xiàn)接口 interface D extends A,B{}class O{} //與一個類多實現(xiàn)其他多個接口相同功效 class C extends O implements D {@Overridepublic void b() {}@Overridepublic void a() {} }實例:
/** 需要實現(xiàn)的功能:* 電腦使用USB設(shè)備* 電腦:電腦能夠使用usb接口插入的設(shè)備* 外接設(shè)備: 鼠標(biāo) 鍵盤 移動硬盤... :實現(xiàn)usb接口定義的規(guī)范* * USB接口:定義規(guī)范,功能的集合*///------------------------------------------------------------//定義電腦類public class Computer {void open(){System.out.println("開機");}//可以使用usb設(shè)備 只要實現(xiàn)了USB接口的設(shè)備都能使用 //將USB接口類型作為useUSB的方法列表,只要是USB接口類型的設(shè)備都可以傳入該方法實現(xiàn)//調(diào)用,此處為USB接口的多態(tài)public void useUSB(USB m){ //接口多態(tài) USB m=new Mouse();;if(m!=null){m.start();m.end();}else{System.out.println("usb設(shè)備無法使用");} }void close(){System.out.println("開機");} } //------------------------------------------------------------ //定義一個USB接口 interface USB {void start();void end(); } //------------------------------------------------------------ //鍵盤類實現(xiàn)USB接口,重寫USB接口的方法 class KeyBoard implements USB{@Overridepublic void start() {System.out.println("開始使用鍵盤"); }@Overridepublic void end() {System.out.println("結(jié)束使用鍵盤");} } //------------------------------------------------------------ //鼠標(biāo)類實現(xiàn)了USB接口,重寫USB接口的方法 class Mouse implements USB{ @Overridepublic void start() {System.out.println("開始使用鼠標(biāo)");}@Overridepublic void end() {System.out.println("結(jié)束使用鼠標(biāo)");} } //------------------------------------------------------------ //測試類 class Test {public static void main(String[] args) {//new一個電腦類對象Computer com=new Computer();//接口多態(tài) 父接口指向子實現(xiàn)類的對象USB usb;//定義父類接口usb=new Mouse();//Mouse類實現(xiàn)USB接口,父類接口USB指向鼠標(biāo)類對象usb=new KeyBoard();//KeyBoard類實現(xiàn)USB接口,父類接口USB指向鍵盤類對象com.open();//開機com.useUSB(usb);//電腦對象調(diào)用方法,使用鍵盤或鼠標(biāo)com.close();//關(guān)機} }總結(jié)
以上是生活随笔為你收集整理的⑦Java SE知识点回顾与小结(面向对象)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小饶学编程之JAVA SE第二部分——W
- 下一篇: win10 软件移动位置信息服务器,如何