自學Java第五章——《面向對象的基本特徵》

面向對象的基本特徵:java

一、封裝面試

二、繼承sql

三、多態數組

 

6.1 封裝

一、好處:安全

(1)隱藏實現細節,方便使用者使用eclipse

(2)安全,能夠控制可見範圍ide

二、如何實現封裝?工具

經過權限修飾符學習

面試題:請按照可見範圍從小到大(從大到小)列出權限修飾符?優化

修飾符 本類 本包 其餘包的子類 任意位置
private × × ×
缺省/省略 × ×
protected ×
public

①權限修飾符能夠修飾什麼?

類(類、接口等)、屬性、方法、構造器、內部類

②分別能夠加什麼權限修飾符?

類(外部類):public和缺省 若是前面有public,那必須文件名和類名一致。

屬性:4種

方法:4種

構造器:4種

內部類:4種

 

三、一般屬性的封裝是什麼樣的?

固然屬性的權限修飾符能夠是private、缺省、protected、public。可是咱們大多數時候,見到的都是private。

若是屬性私有化了,而後給它們配上get/set方法。

set用於修改

get用於獲取

示例代碼:標準Javabean的寫法

public class Student{
   //屬性私有化
   private String name;
   private int age;
   private boolean marry;
   
   //公共的get/set
   public void setName(String n){
       name = n;//這裏由於尚未學習this等,可能還會優化
  }
   public String getName(){
       return name;
  }
   public void setAge(int a){
       age = a;
  }
   public int getAge(){
       return age;
  }
   public void setMarry(boolean m){
       marry = m;
  }
   public boolean isMarry(){//boolean類型的屬性的get方法,習慣使用把get換成is
       return marry;
  }
}

6.2 構造器

一、構造器的做用: (1)和new一塊兒使用建立對象

//調用無參構造建立對象
類名 對象名 = new 類名();

//調用有參構造建立對象
類名 對象名 = new 類名(實參列表);

(2)能夠在建立對象的同時爲屬性賦值

public class Circle{
   private double radius;
   
   public Circle(){
       
  }
   public Circle(double r){
       radius = r;//爲radius賦值
  }
}

 

二、聲明構造器的語法格式:

【修飾符】 class 類名{
   【修飾符】 類名(){//無參構造
       
  }
   【修飾符】 類名(形參列表){//有參構造
       
  }
}

 

三、構造器的特色:

(1)全部的類都有構造器

(2)若是一個類沒有顯式/明確的聲明一個構造器,那麼編譯器將會自動添加一個默認的無參構造

(3)若是一個類顯式/明確的聲明瞭構造器,那麼編譯器將再也不自動添加默認的無參構造,若是須要,那麼就須要手動添加

(4)構造器的名稱必須與類名相同

(5)構造器沒有返回值類型

(6)構造器能夠重載

 

示例代碼:

public class Circle{
   private double radius;
   
   public Circle(){
       
  }
   public Circle(double r){
       radius = r;//爲radius賦值
  }
}

 

6.3 關鍵字this

一、this關鍵字:

意思:當前對象

(1)若是出如今構造器中:表示正在建立的對象

(2)若是出如今成員方法中:表示正在調用這個方法的對象

 

二、this的用法:

(1)this.屬性

當局部變量與成員變量同名時,那麼能夠在成員變量的而前面加「this.」用於區別

(2)this.方法

調用當前對象的成員方法,徹底能夠省略「this.」

(3)this()或this(實參列表)

this()表示調用本類的無參構造

this(實參列表)表示調用本類的有參構造

this()或this(實參列表)要麼沒有,要麼必須出如今構造器的首行

示例代碼:

public class Student{
   private String name;
   private int score;
   
   public Student(){
       
  }
   public Student(String name){
       this.name = name;
  }
   public Student(String name, int score){
       this(name);
  }
   public void setName(String name){
       this.name = name;
  }
   public String getName(){
       return name;
  }
   public void setScore(int score){
       this.score = score;
  }
   public int getScore(){
       return score;
  }
}

 

三、成員變量與局部變量的區別?

這裏只討論實例變量(關於類變量見static部分)

(1)聲明的位置不一樣

成員變量:類中方法外

局部變量:方法中或代碼中

①方法的形參列表

②方法體中局部變量

③代碼塊中的局部變量

(2)運行時在內存中的存儲位置不一樣

成員變量:堆

局部變量:棧

基本數據類型的變量在棧中,引用數據類型的變量在堆中:不許確

(3)修飾符

成員變量:有不少修飾符,例如:權限修飾符

局部變量:不能加權限修飾符,惟一的能加的是final

(4)初始化

成員變量:有默認值

局部變量:沒有默認值,必須手動初始化

(5)生命週期

成員變量:隨着對象的建立而建立,隨着對象被回收而消亡,即與對象同生共死。每個對象都是獨立的。

局部變量:方法調用時才分配,方法運行結束就沒有了。每一次方法調用,都是獨立的

6.4 包

一、包的做用:

(1)能夠避免類重名

有了包以後,類的全名稱就變爲:包.類名

(2)分類組織管理衆多的類

例如:java.lang包,java.util包,java.io包.....

(3)能夠控制某些類型或成員的可見範圍

若是某個類型或者成員的權限修飾缺省的話,那麼就僅限於本包使用

 

二、聲明包的語法格式:

package 包名;

注意:

(1)必須在源文件的代碼首行

(2)一個源文件只能有一個

 

三、包的命名規範和習慣: (1)全部單詞都小寫,每個單詞之間使用.分割 (2)習慣用公司的域名倒置

例如:com.atguigu.xxx;

建議你們取包名時不要使用「java.xx"包

 

四、使用其餘包的類:

前提:被使用的類或成員的權限修飾符是>缺省的

(1)使用類型的全名稱

例如:java.util.Scanner input = new java.util.Scanner(System.in);

(2)使用import 語句以後,代碼中使用簡名稱

 

五、import語句

import 包.類名;
import 包.*;

注意:當使用兩個不一樣包的同名類時,例如:java.util.Date和java.sql.Date。

一個使用全名稱,一個使用簡名稱

 

示例代碼:

package com.atguigu.test;

import java.util.Scanner;

public class Test{
   public static void main(String[] args){
       Scanner input = new Scanner(System.in);
  }
}

 

6.5 eclipse的使用

一、eclipse管理項目和代碼的結構

workspace --> project --> 包-->類...

一個工做空間能夠有多個項目。

 

二、快捷鍵

常規快捷鍵:

Ctrl + S:保存

Ctrl + C:複製

Ctrl + V:粘貼

Ctrl + X:剪切

Ctrl + Y:反撤銷

Ctrl + Z:撤銷

Ctrl + A:全選

 

eclipse中默認的快捷鍵:

Ctrl + 1:快速修復

Alt + /:代碼提示

Alt + ?: Alt + Shift + / 方法的形參列表提示

Ctrl + D:刪除選中行

Ctrl + Alt + ↓:向下複製行

Ctrl + Alt + ↑:向上複製行

Alt + ↓:與下面的行交換位置

Alt + ↑:與下面的行交換位置

Ctrl + Shift + F:快速格式

Ctrl + /:單行註釋,再按一次取消

Ctrl + Shift + /:多行註釋

Ctrl + Shift +\:取消多行註釋

Shift + 回車:在光標下一行插入新航開始編輯

Ctrl + Shift + 回車:在光標上一行插入新航開始編輯

Alt + Shift + A:多行編輯 再按一次退出多行編輯模式

Alt + Shift + S:彈出自動生成代碼的菜單選擇,包括自動生成構造器、get/set、equals......

Ctrl + Shift + O:快速導包

Ctrl + Shift + T:打開某個類的源文件

Ctrl + O:打開某個類型的摘要outline

 

三、快速開發的代碼模板

代碼模板 + Alt + /

(1)main

public static void main(String[] args){

}

(2)sysout

System.out.println();

 

(3)for

for(int i=0; i<數組名.lenght; i++){

}

 

其餘詳細使用見《JavaSE柴林燕相關工具.docx》

6.6 面向對象的基本特徵之二:繼承

一、爲何要繼承?繼承的好處?(理解)

(1)代碼的複用

(2)代碼的擴展

二、如何實現繼承?

語法格式:

【修飾符】 class 子類  extends 父類{
   
}

 

三、繼承的特色

(1)子類會繼承父類的全部特徵(屬性、方法)

可是,私有的在子類中是不能直接使用的

(2)子類不會繼承父類的構造器

由於,父類的構造器是用於建立父類的對象的

(3)子類的構造器中又必須去調用父類的構造器

在建立子類對象的同時,爲從父類繼承的屬性進行初始化用,能夠藉助父類的構造器中的代碼爲屬性賦值。

(4)Java只支持單繼承:一個子類只能有一個「直接」父類

(5)Java又支持多層繼承:父類還能夠有父類,特徵會代代相傳

(6)一個父類能夠同時擁有不少個子類

 

6.7 關鍵字super

super關鍵字:引用父類的,找父類的xx

用法:

(1)super.屬性

當子類聲明瞭和父類同名的成員變量時,那麼若是要表示某個成員變量是父類的,那麼能夠加「super.」

(2)super.方法

當子類重寫了父類的方法,又須要在子類中調用父類被重寫的方法,可使用"super."

(3)super()或super(實參列表)

super():表示調用父類的無參構造

super(實參列表):表示調用父類的有參構造

注意:

(1)若是要寫super()或super(實參列表),必須寫在子類構造器的首行

(2)若是子類的構造器中沒有寫:super()或super(實參列表),那麼默認會有 super()

(3)若是父類沒有無參構造,那麼在子類的構造器的首行「必須」寫super(實參列表)

6.8 方法的重寫

一、方法的重寫(Override)

當子類繼承了父類的方法時,又以爲父類的方法體的實現不適合於子類,那麼子類能夠選擇進行重寫。

 

二、方法的重寫的要求

(1)方法名:必須相同

(2)形參列表:必須相同

(3)修飾符

權限修飾符: >=

(4)返回值類型

若是是基本數據類型和void:必須相同

若是是引用數據類型:<=

在Java中咱們認爲,在概念範圍上:子類 <父類

 

三、重載(Overload)與重寫(Override)的區別

重載(Overload):在同一個類中,方法名相同,形參列表不一樣,和返回值類型無關的兩個或多個方法。

重寫(Override):在父子類之間。對方法簽名的要求見上面。

 

特殊的重載:

public class TestOverload {
public static void main(String[] args) {
B b = new B();
//b對象能夠調用幾個a方法
b.a();
b.a("");//從b對象同時擁有兩個方法名相同,形參不一樣的角度來講,算是重載
}
}
class A{
public void a(){
//...
}
}
class B extends A{
public void a(String str){

}
}

6.9 非靜態代碼塊

一、語法格式

【修飾符】 class 類名{
  {
       非靜態代碼塊
  }
}

二、做用

目的:在建立的過程當中,爲對象屬性賦值,協助完成實例初始化的過程

 

三、何時執行?

(1)每次建立對象時都會執行

(2)優先於構造器執行

 

6.10 實例初始化過程

一、概念描述

  • 實例初始化過程:實例對象建立的過程

  • 實例初始化方法:實例對象建立時要執行的方法

  • 實例初始化方法的由來:它是有編譯器編譯生成的

  • 實例初始化方法的形式:<init>()或<init>(形參列表)

  • 實例初始化方法的構成:

    ①屬性的顯式賦值代碼

    ②非靜態代碼塊的代碼

    ③構造器的代碼

    其中

    ①和②按順序執行,從上往下

    ③在①和②的後面

所以一個類有幾個構造器,就有幾個實例初始化方法。

二、單個類實例初始化方法

示例代碼:

class Demo{
{
System.out.println("非靜態代碼塊1");
}

private String str = assign();//調用方法,來爲str進行顯式賦值

public Demo(){
System.out.println("無參構造");
}
public Demo(String str){
this.str = str;
System.out.println("有參構造");
}

{
System.out.println("非靜態代碼塊2");
}

public String assign(){
System.out.println("assign方法");
return "hello";
}
}

圖解:

 

三、父子類的實例初始化

注意:

(1)原先super()和super(實參列表)說是調用父類的構造器,如今就要糾正爲調用父類的實例初始化方法了

(2)原先super()和super(實參列表)說是必須在子類構造器的首行,如今要糾正爲必須在子類實例初始化方法的首行

結論:

(1)執行順序是先父類實例初始化方法,再子類實例初始化方法

(2)若是子類重寫了方法,經過子類對象調用,必定是執行重寫過的方法

示例代碼:

class Ba{
private String str = assign();
{
System.out.println("(1)父類的非靜態代碼塊");
}
public Ba(){
System.out.println("(2)父類的無參構造");
}
public String assign(){
System.out.println("(3)父類的assign()");
return "ba";
}
}
class Er extends Ba{
private String str = assign();
{
System.out.println("(4)子類的非靜態代碼塊");
}
public Er(){
//super() ==>調用父類的實例初始化方法,並且它在子類實例初始化方法的首行
System.out.println("(5)子類的無參構造");
}

public String assign(){
System.out.println("(6)子類的assign()");
return "er";
}
}
class Test{
   public static void main(String[] args){
       new Er();//612645
  }
}

圖解:

 

6.11 面向對象的基本特徵之三:多態

一、多態:

語法格式:

父類 引用/變量 = 子類的對象;

二、前提:

(1)繼承

(2)方法的重寫

(3)多態引用

 

三、現象:

編譯時看左邊/"父類",運行時看右邊/"子類"。

編譯時,由於按父類編譯,那麼只能父類有的方法,子類擴展的方法是沒法調用的;

執行時必定是運行子類重寫的過的方法體。

示例代碼:

class Person{
public void eat(){
System.out.println("吃飯");
}
public void walk(){
System.out.println("走路");
}
}
class Woman extends Person{
public void eat(){
System.out.println("細嚼慢嚥的吃飯");
}
public void walk(){
System.out.println("婀娜多姿走路");
}
public void shop(){
System.out.println("買買買...");
}
}
class Man extends Person{
public void eat(){
System.out.println("狼吞虎嚥的吃飯");
}
public void walk(){
System.out.println("大搖大擺的走路");
}
public void smoke(){
System.out.println("吞雲吐霧");
}
}
class Test{
   public static void main(String[] args){
       Person p = new Woman();//多態引用
       p.eat();//執行子類重寫
       p.walk();//執行子類重寫
       //p.shop();//沒法調用
  }
}

 

四、應用:

(1)多態參數:形參是父類,實參是子類對象

(2)多態數組:數組元素類型是父類,元素存儲的是子類對象

示例代碼:多態參數

class Test{
   public static void main(String[] args){
       test(new Woman());//實參是子類對象
       test(new Man());//實參是子類對象
  }
   public static void test(Person p){//形參是父類類型
       p.eat();
       p.walk();
  }
}

示例代碼:多態數組

class Test{
   public static void main(String[] args){
       Person[] arr = new Person[2];//多態數組
       arr[0] = new Woman();
       arr[1] = new Man();
       
       for(int i=0; i<arr.length; i++){
           all[i].eat();
           all[i].walk();
      }
  }
}

 

五、向上轉型與向下轉型:父子類之間的轉換

(1)向上轉型:自動類型轉換

當把子類的對象賦值給父類的變量時(即多態引用時),在編譯時,這個對象就向上轉型爲父類。此時就看不見子類「特有、擴展」的方法。

(2)向下轉型:強制轉換。有風險,可能會報ClassCastException異常。

當須要把父類的變量賦值給一個子類的變量時,就須要向下轉型。

要想轉型成功,必須保證該變量中保存的對象的運行時類型是<=強轉的類型

示例代碼:

class Person{
//方法代碼省略...
}
class Woman extends Person{
   //方法代碼省略...
}
class ChineseWoman extends Woman{
//方法代碼省略...
}
 public class Test{
    public static void main(String[] args){
//向上轉型
Person p1 = new Woman();
//向下轉型
Woman m = (Woman)p1;
//p1變量中實際存儲的對象就是Woman類型,和強轉的Woman類型同樣

//向上轉型
Person p2 = new ChineseWoman();
//向下轉型
Woman w2 = (Woman) p2;
//p2變量中實際存儲的對象是ChineseWoman類型,強制的類型是Woman,ChineseWoman<Woman類型    
    }
}

六、instanceof

表達式語法格式:

對象/變量  instanceof  類型

運算結果:true 或 false

做用:

用來判斷這個對象是否屬於這個類型,或者說,是不是這個類型的對象或這個類型子類的對象

 

示例代碼:

class Person{
//方法代碼省略...
}
class Woman extends Person{
   //方法代碼省略...
}
class ChineseWoman extends Woman{
//方法代碼省略...
}
 public class Test{
    public static void main(String[] args){
        Person p = new Person();
        Woman w = new Woman();
        ChineseWoman c = new ChineseWoman();
       
        if(p instanceof Woman){//false
           
        }
        if(w instanceof Woman){//true
           
        }
        if(c instanceof Woman){//true
           
        }
    }
}
相關文章
相關標籤/搜索