溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

java面向?qū)ο蟮囊馑际鞘裁?/h1>
發(fā)布時間:2020-07-15 14:13:31 來源:億速云 閱讀:265 作者:Leah 欄目:編程語言

這篇文章運用簡單易懂的例子給大家介紹java面向?qū)ο蟮囊馑际鞘裁矗a非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

11、子類訪問父類和方法覆寫

子類不能直接訪問父類的私有成員;

但是子類可以調(diào)用父類中的非私有方法來間接訪問父類的私有成員。

Person類中有私有字段name,Student繼承Person

new Sudent().name;                ×

new Student().getName();      √

子類拓展父類(子類是父類的一種特殊情況)

主要是以父類為基礎(chǔ),然后添加屬于自己的字段和方法。

方法覆寫產(chǎn)生原因:

當(dāng)父類中某個方法不適合于子類時,子類出現(xiàn)父類一模一樣的方法.

判斷必殺技:子類方法前加上@Override能編譯通過,表明是方法的覆寫。

調(diào)用被覆蓋的父類方法:使用super.方法名(實參);

方法覆寫時應(yīng)遵循的原則(一同兩小一大):

(一同):

方法簽名必須相同;

(兩小):

子類方法的返回值類型比父類方法的返回值類型更小或相等

子類方法聲明拋出的異常應(yīng)比父類方法申明拋出的異常更小或相等;

(一大):子類方法的訪問權(quán)限應(yīng)比父類方法更大或相等;

子類需要覆寫父類方法。

當(dāng)父類的某個方法不適合于子類本身的特征行為時就當(dāng)覆寫父類中應(yīng)當(dāng)改變的方法。

12、super關(guān)鍵字和調(diào)用父類構(gòu)造方法

表示父類對象的默認(rèn)引用

如果子類要調(diào)用父類被覆蓋的實例方法,可用super作為調(diào)用者調(diào)用父類被覆蓋的實例方法。

使用super調(diào)用父類方法

使用super調(diào)用父類的構(gòu)造方法

調(diào)用構(gòu)造方法

本類中調(diào)用另一個重載構(gòu)造方法用this(參數(shù)列表)

子類構(gòu)造方法調(diào)用父類構(gòu)造方法用super(參數(shù)列表)

子類調(diào)用父類的構(gòu)造方法時:

super必須放在第一句

Java在執(zhí)行子類的構(gòu)造方法前會先調(diào)用父類無參的構(gòu)造方法,其目的是為了對繼承自父類的成員做初始化操作。

子類在創(chuàng)建對象的時候,默認(rèn)調(diào)用父類的無參構(gòu)造方法,要是子類構(gòu)造方法中顯示指定調(diào)用父類其他構(gòu)造方法,就調(diào)用指定的父類構(gòu)造方法,取消調(diào)用父類無參構(gòu)造方法。

Eg:
 
package reviewDemo;
 
 
 
class A{
 
   String name;
 
   A(){
 
      System.out.println("父類默認(rèn)隱式的構(gòu)造方法!");
 
   }
 
  
 
   A(String name){
 
      System.out.println("父類顯式的構(gòu)造方法!");
 
   }
 
}
 
 
 
class B extends A{
 
  
 
   B(){
 
      super(null);
 
      System.out.println("子類默認(rèn)隱式的構(gòu)造方法!");
 
   }
 
}
 
 
 
public class Demo10 {
 
   public static void main(String[] args) {
 
      new B();
 
   }
 
}

13、面向?qū)ο笾鄳B(tài)

多態(tài):指同一個實體同時具有多種形式

好比,你去面館吃面,說我要吃面,那么;老板給我牛肉面,雞蛋面等都可以,

這就是說"面"有多種形態(tài),也就是說實體有多種形態(tài);

編譯時的類型由聲明該變量時使用的類型決定,運行時的類型由實際賦給變量的對象決定。

如果編譯時類型和運行時類型不同,就出現(xiàn)多態(tài)。

Eg:

前提:Student  extends   Person:

Person p = new Person();

Student s = new Student();

Person p = new Student();//多態(tài)

引用關(guān)系:父類變量指向子類實例對象

實現(xiàn)多態(tài)的機制:

父類的引用變量可以指向子類的實例對象,而程序調(diào)用的方法在運行期才動態(tài)綁定,就是引用變量所指向的真正實例對象的方法,也就是內(nèi)存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。

多態(tài)的作用

把不同的子類對象都當(dāng)作父類來看,可以屏蔽不同子類對象之間的差異,寫出通用的代碼,做出通用的編程,以適應(yīng)需求的不斷變化。

只修改方法的實現(xiàn),不必修改方法的聲明

繼承是多態(tài)產(chǎn)生的前提條件;

分類:

編譯時多態(tài):方法重載

運行時多態(tài):方法覆寫

Eg:
 
package test;
 
 
 
class Dog{
 
   void eat(){
 
      System.out.println("一般的狗吃一般的狗糧!");
 
   }
 
}
 
 
 
class HashDog extends Dog{
 
   void eat(){
 
      System.out.println("哈士奇吃哈士奇的狗糧!");
 
   }
 
}
 
 
 
class ZangAoDog extends Dog{
 
   void eat(){
 
      System.out.println("藏獒吃藏獒的狗糧!");
 
   }
 
}
 
 
 
//定義一個動物園喂的方法
 
class Zoo{
 
  
 
   void feed(Dog d){
 
      d.eat();
 
   }
 
  
 
}
 
 
 
public class Demo11 {
 
   public static void main(String[] args) {
 
     
 
      Dog hd = new HashDog();
 
     
 
      Dog zd = new ZangAoDog();
 
     
 
      Zoo z = new Zoo();
 
      z.feed(hd);
 
      z.feed(zd);
 
   }
 
}

輸出:

哈士奇吃哈士奇的狗糧!

藏獒吃藏獒的狗糧!

14、引用變量類型轉(zhuǎn)換

向上轉(zhuǎn)型(子類→父類):(自動完成)

父類名稱 父類對象 = 子類實例 ;

向下轉(zhuǎn)型(父類→子類):(強制完成)

子類名稱 子類對象 = (子類名稱)父類實例 ;

對象名   instanceof  類

判斷指定的變量名此時引用的真正類型是不是當(dāng)前給出的類或子類;

我的總結(jié):對象的類型和類必須有繼承關(guān)系

Eg:
class A extends B{}
 
B b = new A();
If(b instanceof A){  ...
}

2、面向?qū)ο螅?)

1、基本數(shù)據(jù)類型的包裝類

引言:Java提倡的萬物皆對象,但是數(shù)據(jù)類型的劃分出現(xiàn)了基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,那么我們怎么能把基本數(shù)據(jù)類型稱為對象呢?

java面向?qū)ο蟮囊馑际鞘裁?></p><p>除了Integer和Character定義的名稱和對應(yīng)的基本類型差異大,其他六種都是將首字母大寫就可以了。</p><p>Integer,Byte,Float,Double,Short,Long都是Number類的子類。(Number類后面講);</p><p>Character和Boolean都是Object直接子類;</p><p>8個類都是final修飾的(不可被繼承)。</p><p><strong>2、基本數(shù)據(jù)類型和包裝類相互轉(zhuǎn)換</strong></p><p><span>把基本數(shù)據(jù)類型 → 包裝類:</span></p><p>通過對應(yīng)包裝類的構(gòu)造方法實現(xiàn)</p><p>除了Character外,其他包裝類都可以傳入一個字符串參數(shù)構(gòu)建包裝類對象。</p><p>包裝類 → 基本數(shù)據(jù)類型</p><p>包裝類的實例方法xxxValue();    // xxx表示包裝類對應(yīng)的基本數(shù)據(jù)類型</p><pre class=Eg: boolean bool = false; Boolean b2 = new Boolean(bool); Integer i = new Integer(3); int i2 = i.intValue(); Boolean b1 = new Boolean("TRue");//true boolean b2 = b1.booleanValue(); Float f = new Float("3.14");//3.14 Integer i2 = new Integer("123s");//NumberFormatException

備注:

自動裝箱&自動拆箱

jdk1.5開始出現(xiàn)的特性:

自動裝箱:可把一個基本類型變量直接賦給對應(yīng)的包裝類對象或則Object對象

自動拆箱:允許把 包裝類對象直接賦給對應(yīng)的基本數(shù)據(jù)類型

Eg:
 
Integer i = 3;//裝箱
 
int i2 = i;//拆箱
 
Object flag = new Boolean(false);
 
if(flag instanceof Boolean){
 
        Boolean b = (Boolean)flag;
 
        boolean b2 = b;
 
}

3、基本類型和String之間的轉(zhuǎn)換

String → 基本類型,除了Character外所有的包裝類提供parseXxx(String s)靜態(tài)方法,用于把一個特定的字符串轉(zhuǎn)換成基本類型變量;

基本類型 → String,String 類有靜態(tài)方法valueOf(),用于將基本類型的變量轉(zhuǎn)換成String類型。

String str = "17";
int i = Integer.parseInt(str);//String  --> 基本類型
String s1 = String.valueOf(i);//基本類型 --> String

4、Object類

所有類的公共父類,一旦一個類沒有顯示地繼承一個類則其直接父類一定是Object。

一切數(shù)據(jù)類型都可用Object接收

class OOXX  extends Object{}等價于class ooXX {}

常見方法

public boolean equals(Object obj):對象比較

public int hashCode():取得該對象的Hash碼

public String toString():對象描述

Object類的 toString()方法:“對象的描述”

建議所有類都覆寫此方法

直接打印輸出對象時,會調(diào)用該對象的toString()方法。//可以不寫出來

打印對象的時候,實際調(diào)用的對象實際指向的類的自我描述;

全限定類名+@+十六進(jìn)制的hashCode值,等價于

全限定類名+@+IntegertoHexString(該對象.hashCode)

equals也是判斷是否指向同一個對象

沒有實際意義,有必要可以重寫

public boolean equals(Object obj) {}

String 覆寫了 Object的equals方法:只比較字符的序列是否相同

==用于判斷兩個變量是否相等

基本類型:

引用類型:必須指向同一個對象,才true

只能比較有父子或平級關(guān)系的兩個對象

new String("1") == new String("1"); ?

5、代碼塊

代碼塊指的是使用"{}"括起來的一段代碼,根據(jù)代碼塊存在的位置可以分為4種:

普通代碼塊;

構(gòu)造代碼塊;

靜態(tài)代碼塊;

同步代碼塊(線程同步的時候講解)。

代碼塊里變量的作用域:

只在自己所在區(qū)域(前后的{})內(nèi)有效;

普通代碼塊:

普通代碼塊就是直接定義在方法或語句中定義的代碼塊:

public void show(){

普通代碼塊

}

構(gòu)造代碼塊:

直接寫在類中的代碼塊:

優(yōu)先于構(gòu)造方法執(zhí)行,每次實例化對象之前都會執(zhí)行構(gòu)造代碼塊。

Eg:
 
public class Demo {
 
    {
 
               System.out.println("我是構(gòu)造代碼塊");
 
    }
 
    public Demo(){
 
                System.out.println("我是構(gòu)造方法");
 
    }
 
    public static void main(String[] args) {
 
               Demo d1  = new Demo();
 
               Demo d2  = new Demo();
 
    }
 
}

靜態(tài)代碼塊

使用static 修飾的構(gòu)造代碼塊:

優(yōu)先于主方法執(zhí)行,優(yōu)先于構(gòu)造代碼塊執(zhí)行,不管有創(chuàng)建多少對象,靜態(tài)代碼塊只執(zhí)行一次,可用于給靜態(tài)變量賦值;

Eg:
 
package reviewDemo;
 
/**
 * 測試各代碼塊的優(yōu)先級
 * 優(yōu)先級順序:靜態(tài)代碼塊 ?。尽?gòu)造代碼塊?。尽∑胀ùa塊
 * 備注:無論創(chuàng)建幾個對象,靜態(tài)代碼塊只執(zhí)行一次!
 */
 
 
 
public class Demo13 {
 
   Demo13(){
 
      System.out.println("我是構(gòu)造方法!");
 
   }
 
   {
 
      System.out.println("我是構(gòu)造代碼塊!");//實例化對象的時候才會去調(diào)用!
 
   }
 
   static{
 
      System.out.println("我是靜態(tài)代碼塊!");
 
   }
 
  
 
   public static void main(String[] args) {
 
      new Demo13();
 
      new Demo13();//再次創(chuàng)建對象,證明無論創(chuàng)建幾次對象,靜態(tài)代碼塊都只執(zhí)行一次
 
      System.out.println("我是普通代碼塊!");
 
   }
 
}

輸出:

我是靜態(tài)代碼塊!

我是構(gòu)造代碼塊!

我是構(gòu)造方法!

我是構(gòu)造代碼塊!

我是構(gòu)造方法!

我是普通代碼塊!

6、構(gòu)造方法的私有化

有的時候我們?yōu)榱吮苊馔饨鐒?chuàng)建某類的實例,就將某類的構(gòu)造方法私有化,即將它的構(gòu)造方法用private修飾:

外界如何用到?

提供get方法!不提供的話外界就沒法創(chuàng)建對象?。▽Ψ瓷錈o效)

Eg:package reviewDemo;
 
 
class Stu{
 
   //將構(gòu)造方法私有化
 
   private Stu(){
 
     
 
   }
 
}
 
 
 
public class Demo15 {
 
   public static void main(String[] args) {
 
      Stu s = new Stu();
 
   }
 
}

Singleton模式(單例模式) 餓漢式和懶漢式

目的:整個應(yīng)用中有且只有一個實例,所有指向該類型實例的引用都指向這個實例。

好比一個國家就只有一個皇帝(XXX),此時每個人叫的“皇帝”都是指叫的XXX本人;

常見單例模式類型:

餓漢式單例:直接將對象定義出來

懶漢式單例:只給出變量,并不將其初始化;

我的總結(jié):

餓漢式,static修飾,隨著類的加載而加載,會損耗性能,但是方法相對簡單

懶漢式  第一次用的時候相對較慢,因為需要加載!線程,不安全!

 package reviewDemo;
 
//單例模式
 
 
 
//餓漢式,直接把對象構(gòu)造出來
 
class SingleDemo{
 
   private static SingleDemo s1 = new SingleDemo();
 
   private SingleDemo(){
 
      //提供私有化的構(gòu)造方法,那么外界就不能構(gòu)造對象了!
 
   }
 
  
 
   public static SingleDemo getS1() {
 
      return s1;
 
   }
 
}
 
 
 
//懶漢式,先定義,但是不創(chuàng)建對象
 
class SingleDemo2{
 
   private static SingleDemo2 s3 ;
 
  
 
   private SingleDemo2(){
 
      //提供私有化的構(gòu)造方法,那么外界就不能構(gòu)造對象了!
 
   }
 
  
 
   public static SingleDemo2 getS3() {//這是一個方法,返回值為創(chuàng)建的對象!
 
      if(s3 == null){
 
         s3 = new SingleDemo2();
 
      }//和餓漢式的區(qū)別,此時才來創(chuàng)建對象!
 
      return s3;
 
   }
 
}
 
 
 
public class Demo14 {
 
   public static void main(String[] args) {
 
      SingleDemo s1 = SingleDemo.getS1();
 
      SingleDemo s2 = SingleDemo.getS1();
 
     
 
      SingleDemo2 s3 = SingleDemo2.getS3();
 
      SingleDemo2 s4 = SingleDemo2.getS3();
 
     
 
      System.out.println(s1 == s2);
 
      System.out.println(s3 == s4);
 
     
 
   }
 
}
 
 
 
輸出:true true
 
 
 
備注:枚舉更加安全些
 
package reviewDemo;
 
 
 
enum Stu{
 
   jake;
 
   //將構(gòu)造方法私有化起來,反射也不能創(chuàng)建對象,安全
 
   private Stu(){
 
     
 
   }
 
}
 
 
 
public class Demo15 {
 
   public static void main(String[] args) {
 
   }
 
}

8、final 關(guān)鍵字

final可以修飾類,方法,變量。

final修飾類不可以被繼承,但是可以繼承其他類。

final修飾的方法不可以被覆寫,但可以覆寫父類方法。

final修飾的變量稱為常量,這些變量只能賦值一次。

內(nèi)部類在局部時,只可以訪問被final修飾的局部變量。

final修飾的引用類型變量,表示該變量的引用不能變,而不是該變量的值不能變;

Eg:
 
package reviewDemo;
 
 
 
final class Name{
 
}
 
 
 
class NewName extends Name{//ERROR,報錯,因為Name有final修飾
 
}
 
 
 
public class Demo15 {
 
   public static void main(String[] args) {
 
   }
 
}

9、抽象類

當(dāng)編寫一個類時,我們往往會為該類定義一些方法,這些方法是用來描述該類的行為方式,那么這些方法都有具體的方法體。

但是有的時候,某個父類只是知道子類應(yīng)該包含怎么樣的方法,但是無法準(zhǔn)確知道子類如何實現(xiàn)這些方法。

抽象方法的定義:通過abstract關(guān)鍵字來修飾的類稱為抽象類;

總結(jié):抽象類用private修飾,里面可以有用private修飾的方法(沒有方法體),強制子類進(jìn)行覆寫;

可以理解為:具有某些公共方法的一個總結(jié)類。

可以定義被abstract修飾的抽象方法

抽象方法只有返回類型和方法簽名,沒有方法體。

備注:

抽象類可以含有普通方法

抽象類不能創(chuàng)建實例對象(不能new)

需要子類覆蓋掉所有的抽象方法后才可以創(chuàng)建子類對象,否則子類也必須作為抽象類

列舉常見的幾個抽象類:

流的四個基本父類

InputStream,OutputStream,Reader,Writer

我的總結(jié):

抽象類是類的一種特殊情況:據(jù)有類的一切特點,但是不能實例化;一般的都得帶有抽象方法。

抽象類不可以實例化,有時看到的近似實例化是多態(tài)機制的體現(xiàn),并不是真正的實例化。

Eg:
 
Socket s = new Socket();
 
OutputStream os = s.getOutputStream();
 
左邊是OutputStream類型變量的聲明,右邊是獲取抽象類OutputStream的一個實例對象!
 
 
package testDemo2;
 
 
 
abstract class Person{
 
}
 
 
 
class Student extends Person{
 
}
 
 
public class Demo2 {
 
   public static void main(String[] args) {
 
      Person p = new Student();//體現(xiàn)的是多態(tài),父類聲明實例化子類對象。而不是抽象類實例化
 
   }
 
}

abstract方法

分析事物時,發(fā)現(xiàn)了共性內(nèi)容,就出現(xiàn)向上抽取。會有這樣一種特殊情況,就是功能聲明相同,但功能主體不同。

那么這時也可以抽取,但只抽取方法聲明,不抽取方法主體。那么此方法就是一個抽象方法。

abstract [非private訪問修飾符] 返回值類型 方法名稱(參數(shù)列表);

抽象方法要存放在抽象類中。

抽象方法也可以存在于接口中

Eg:
 
package reviewDemo;
 
 
 
abstract class Person3{
 
   abstract void show();
 
   abstract void inof();
 
   void turn(){
 
   }
 
}
 
 
 
class NewP extends Person3{
 
   @Override
 
   void show() {
 
   }
 
 
 
   @Override
 
   void inof() {
 
   }
 
   //不覆寫的話會報錯
 
}
 
 
 
public class Demo15 {
 
   public static void main(String[] args) {
 
      //new Person3();報錯!因為抽象類不可以實例化
 
   }
 
}

10、抽象類的體現(xiàn)-模板模式

抽象類是多個具體子類抽象出來的父類,具有高層次的抽象性;以該抽象類作為子類的模板可以避免子類設(shè)計的隨意性;

抽象類的體現(xiàn)主要就是模板模式設(shè)計,抽象類作為多個子類的通用模板,子類在抽象類的基礎(chǔ)上進(jìn)行拓展,但是子類在總體上大致保留抽象類的行為方式;

編寫一個抽象父類,該父類提供了多個子類的通用方法,并把一個或多個抽象方法留給子類去實現(xiàn),這就是模板設(shè)計模式;

模板模式應(yīng)用的簡單規(guī)則:

1.抽象父類可以只定義需要使用的某些方法,其余留給子類去實現(xiàn);

2.父類提供的方法只是定義了一個通用算法,其實現(xiàn)必須依賴子類的輔助;

我的總結(jié):

如果父類的方法不想被子類覆寫,那么可以在前面加上final關(guān)鍵字修飾。

Eg:
 
package reviewDemo;
 
//模板模式
 
 
 
//抽象類中包含很多的抽象方法,子類必須去覆寫!
 
abstract class Method{
 
   abstract double mul();//返回值類型如果是void的話,下面報錯,因為沒有返回值,無法引用!
 
   abstract double divid();
 
   void show(){
 
      System.out.println("面積是:"+mul());//周長
 
      System.out.println("面積是:"+divid());//面積
 
   }
 
}
 
 
 
class Square extends Method{
 
   double d;
 
  
 
   public Square(double d) {
 
      super();
 
      this.d = d;
 
   }
 
 
 
   @Override
 
   double mul() {
 
      return d * d;
 
   }
 
 
 
   @Override
 
   double divid() {
 
      return 4 * d;
 
   }
 
}
 
 
 
class Cirle extends Method{
 
   double r;
 
  
 
   public Cirle(double r) {
 
      super();
 
      this.r = r;
 
   }
 
 
 
   @Override
 
   double mul() {
 
      return 2 * 3.14 * r;
 
   }
 
 
 
   @Override
 
   double divid() {
 
      return 3.14 * r * r;
 
   }
 
}
 
 
 
public class Demo16 {
 
   public static void main(String[] args) {
 
      Square s = new Square(5);
 
      s.show();
 
      Cirle c = new Cirle(4);
 
      c.show();
 
   }
 
}

關(guān)于java面向?qū)ο蟮囊馑际鞘裁淳头窒淼竭@里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)
AI