1. 程式人生 > >java面向物件(上)

java面向物件(上)

面向物件

  • java是面向物件的程式設計語言,java提供了定義 類 成員變數 方法的基本功能
  • java也支援面向物件的三大特徵:封裝,繼承,多型。
  • java提供了 private protected 和 public 三個訪問控制修飾符來實現 良好的封裝。提供了 extends關鍵字讓子類繼承父類,繼承之後就可以得到父類成員變數和方法。繼承是實現類複用的重要手段。當然也可以通過組合來進行復用。
  • 特徵:
  • 是一種更加符合我們思想習慣的思想
  • 可以將複雜的事情簡單化
  • 將我們從執行者變成指揮者
  • 開發:
  • 不斷建立物件,使用物件,指揮物件。
  • 設計:
    • 考慮管理物件之間的關係

類和物件

  • .定義類:
  • 在面向物件的程式設計過程中有兩個重要概念:類(class)和物件(object,或instance)。 其中類是某一批物件的抽象。可以把類理解成某種概念;物件才是具體的存在。 類和物件都是核心。
Java語言裡定義類的簡單語法:
【修飾符】 class 類名
{
零到多個構造器定義:
零到多個成員變數;
零到多個方法;
}
修飾符:public,final ,abstract 或者完全省略。

  • 類名:合法識別符號,一個或多個有意義單詞連綴而成,每個單詞首寫字母大寫,單詞之間不用任何間隔符。

  • 成員:構造器;成員;方法。 成員可以相互呼叫,static修飾的成員不能訪問沒有static修飾的成員。

    • 定義成員變數: 【修飾符】 型別 成員變數名 【=預設值】; 修飾符:public protected private static final
    • 定義方法格式: 【修飾符】 方法返回值型別 方法名(形參列表) { //零到多條可執行性語句組成的方法體 } 修飾符:public protected private static final abstract。
    • 構造器特點: 構造器既不能定義返回值型別,也不能使用void宣告構造器沒有返回值,如果程式設計師手動新增返回值型別或者void 系統會將其當成方法處理 構造器將不復存在。 類定義之後,就以使用該類了。java的類大致如下作用: **定義變數 **建立物件 **呼叫類的類方法和訪問類的類變數

static修飾符::::【重點】 作用:為了區別(方法 變數 內部類 初始化模組)這四個成員 是屬於類本身還是屬於例項,有static修飾的是類本身 木有修飾的是例項。

java語言通過new關鍵字呼叫構造器

物件產生和使用

  • 建立物件的根本途徑是構造器,通過new關鍵字來呼叫某個類的構造器即可建立這個類的例項

//使用Person類定義一個person型別的變數 Person p; //通過new關鍵字呼叫Person類的構造器,返回一個Person例項 //將該Person類的例項賦給p便量; p = new Person();

上面的程式碼也可以簡化:

//定義p變數同時併為p變數賦值 Person p = new Person();

  • 建立物件後就可以使用該物件了;Java的物件大致有如下作用: ** 訪問物件的例項變數: **呼叫物件的方法:
  • 當權限允許的時候類裡定義的方法 變數 都可以通過類或者例項呼叫 類或例項訪問方法或成員變數的語法: **類.類變數|方法 **例項.變數|方法 其中,static修飾的變數和方法既可以通過例項呼叫 也可以通過類呼叫。

陣列練習:引用型別陣列初始化

//為了更好的說明引用型別的執行過程 先定義一個person類  所有類都是引用型別
class Person{
         int age; //年齡
         double height; //身高
    //定義一個info方法
    void info(int age,int height)
	{
        System.out.println("我的年齡是:"+ age + ",我的身高是:"+ height);
    }
}
class  ReferenceArrayTest
{
    public static void mian(String[] args)
    {
        //定義一個students型別的陣列變數,其型別是person[];
        Person[] students;
        //執行動態初始化
        students = new Person[2];
        //建立一個person例項 並把這個例項賦給zhang變數
        Person zhang = new Person();
        //為zhang賦值
        zhang.age = 16;
        zhang.height = 178;
        //建立一個person例項,並把這個例項賦給lee變數
        Person lee = new Person();
        //為lee賦值
        lee.age = 19;
        lee.height = 180;
        //分別將zhang和lee賦給students
        students[0] = zhang;
        students[1] = lee;
        students[0].info();
        students[1].info();
    }
}

一個物件的記憶體圖:

理解物件在記憶體中的流程

成員變數和區域性變數

出現的位置: 成員變數:類中方法外: 區域性變數:方法內或者方法宣告上: 記憶體的位置: 成員變數:堆記憶體: 區域性變數:棧記憶體; 生命週期: 成員變數:隨物件存在而存在 隨物件消失而消失 區域性變數:隨著方法呼叫而存在,隨著方法呼叫完畢而消失。 初始化值不同: 成員變數:有預設的初始化值 區域性變數:沒有預設的初始化值 必須先定義 賦值 才能被使用。 注意事項:成員變數和區域性變數可以名稱相同,在方法中使用就近原則

方法的形參

  • 形參有基本型別和引用型別。
    • 基本型別,形參是什麼資料型別 實參就傳什麼型別 這裡其實是根據實參 改形參
    • 引用型別,當形參是一個類型別時 這是實參要穿的是這個類的物件。。。。。
例如:
//形式引數是基本型別
class Demo {
	public int sum(int a,int b) {
		return a + b;
	}
}


//形式引數是引用型別
class Student {
	public void show() {
		System.out.println("我愛學習");
	}
}
class StudentDemo {
	//如果你看到了一個方法的形式引數是一個類型別(引用型別),這裡其實需要的是該類的物件。
	public void method(Student s) { //呼叫的時候,把main方法中的s的地址傳遞到了這裡 Student s = new Student();
		s.show();
	}
}
class ArgsTest {
	public static void main(String[] args) {
		//形式引數是基本型別的呼叫
		Demo d = new Demo();
		int result = d.sum(10,20);
		System.out.println("result:"+result);
		System.out.println("--------------");
		
		//形式引數是引用型別的呼叫
		//需求:我要呼叫StudentDemo類中的method()方法
		StudentDemo sd = new StudentDemo();

		//建立學生物件
		Student s = new Student();
		sd.method(s); //把s的地址給到了這裡


	}
}
  • 形參個數可變的方法

    • Java允許在方法的形參裡存在且最多存在一個形參個數可變的形參,而且可數可變的形參必須在最後,【在該形參的型別後面加 … 則表明該形參可接受多個引數值,多個引數值被當做陣列傳入】
例如:
----------------------------------------------------------------------------------------------------------------------
public class Varargs
{
//定義了形參個數可變的方法
public static void test(int a,String... books)
{
//books 被當做陣列處理
for (String tmp :books)
{
System.out.println(tmp);
}
//輸出整形a變數
System.out.println(a);
}
pubilc static void main(String[] args)
{
//呼叫方法test
test(5,"瘋狂Java講義","輕量級Java EE 企業應用實戰");
}
}
執行結果:
瘋狂Java講義
輕量級Java EE 企業應用實戰
5
方法練習:(不死神兔)
(斐波那楔數列)
class Fibonacci
{
    private long[] f1 ;
    public void Fn()
    {
        int n;
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入一個數:");
        n = sc.nextInt();
        f1 = new long[n];
        f1[0] = 1;
        f1[1] = 1;
        for ( int i = 2 ;i < f1.length ; i++)
        {
            f1[i] = f1[i - 1] + f1[i - 2];
        }
    }
    public void Print()
    {
        for (int i = 0;i < f1.length ; i++) {
            System.out.println(f1[i]);
        }
    }
}
class FibonacciTest
{
    public static void main(String[] args)
    {
       Fibonacci F = new Fibonacci();
        F.Fn();
        F.Print();
    }
}

匿名物件

  • 定義:沒有名字的物件
  • 應用場景: a。呼叫方法:當僅僅只呼叫一次的時候,可以使用,呼叫完畢後變成垃圾,被回收。 b。匿名物件可以作為形式引數傳遞
例如:
-----------------------------------------------------------------------------------------------------------------
class Student      //類
{
public void show()     //方法
{
System.out.println("我愛學習");
       }
}
class StudentDome   //類
{
public void method(Student s)    //方法  引數是物件
{
   s.show();    //呼叫方法
}
}
class NonameDome
{
public static void main(String[] args)
{
//帶名字的呼叫
Student s = new Student();   //s就是物件的名字
s.show();   //呼叫方法
//匿名呼叫;
new Student();    //物件沒有名字
new Student().show     //呼叫方法
//升級
Student s = new Student();    
StudentDome sd = new StudentDome();
sd.method(s)
//再來
sd.method(new Student());
//再來
new.StudentDome().method(new Student());
}

封裝概述:隱藏物件的屬性和實現細節,僅提供一個公共訪問方式。

  • 優點:
    • 隱藏實現細節提供公共訪問方式
    • 提高了程式碼的複用性。
    • 提高安全性。
  • 封裝原則:
    • 將不需要向外界提供的內容都隱藏起來。
    • 把屬性隱藏,提供公共方式進行訪問
  • 訪問控制符:
    • java提供了3個訪問控制符:private , protected , public. 分別代表三個訪問控制級別, private—》default—》protect—》public。

private(當前類訪問許可權):如果一個類的一個成員(成員變數,方法,構造器等)使用private訪問控制符來修飾,則這個成員只能在當前類裡被訪問。很顯然,這個訪問控制符用於修飾成員變數最合適,使用它來修飾成員變數可以將它隱藏在這個類的內部。【 1 成員變數修飾 2 提供 getXxx和setXxx的方法】 default(包訪問許可權):如果一個類裡的一個成員(包括成員變數,方法 ,構造器等)或者一個外部類不使用任何訪問控制符修飾,就稱她是包訪問許可權的,default訪問控制的成員或者外部類可以被相同包下的其他類訪問。 protected(子類訪問許可權):如果一個類的一個成員(成員變數,方法,構造器等)使用protected訪問控制符來修飾,那麼這個成員既可以唄同一個包中的其他類訪問,也可以被不同包中的子類訪問。通常情況下 如果一個方法被這個符修飾,通常是希望其子類來重寫這個方法。 public:(公共訪問許可權):這是最寬鬆的訪問控制級別,如果一個類裡的一個成員(包括成員變數,方法 ,構造器等)或者一個外部類被public訪問控制符修飾,則他可以被任何類 訪問

static關鍵字:針對所有物件共享的成員變數值

  • 靜態的意思。可以修飾成員變數和成員方法。

  • 靜態的特點: A:隨著類的載入而載入 B:優先與物件存在 C:被類的所有物件共享 這其實也是我們判斷該不該使用靜態的依據。 舉例:飲水機和水杯的問題思考 D:可以通過類名呼叫 既可以通過物件名呼叫,也可以通過類名呼叫,建議通過類名呼叫。

  • 靜態的記憶體圖 靜態的內容在方法區的靜態區

  • 靜態的注意事項 A:在靜態方法中沒有this物件 B:靜態只能訪問靜態(程式碼測試過)

  • 靜態變數和成員變數的區別

  • 所屬不同 靜態變數:屬於類,類變數 成員變數:屬於物件,物件變數,例項變數

    • 記憶體位置不同 靜態變數:方法區的靜態區 成員變數:堆記憶體
    • 生命週期不同 靜態變數:靜態變數是隨著類的載入而載入,隨著類的消失而消失 成員變數:成員變數是隨著物件的建立而存在,隨著物件的消失而消失
    • 呼叫不同 靜態變數:可以通過物件名呼叫,也可以通過類名呼叫 成員變數:只能通過物件名呼叫
  • main方法是靜態的

    • public:許可權最大
    • static:不用建立物件呼叫
    • void:返回值給jvm沒有意義
    • main:就是一個常見的名稱。
    • String[] args:可以接收資料,提供程式的靈活性

格式:java MainDemo hello world java java MainDemo 10 20 30

包: 資料夾

  • java允許將一組功能相關的類放在一個package裡 從而組成邏輯上的類庫單元,
  • 格式:package packageName ; 注意:package語句必須作為原始檔的第一行非註釋性語句。一個原始檔只能制定一個包。 一旦使用這個語句,則意味著原始檔裡定義的類都屬於這個包(package)位於包中的每個類的完整類名都應該為:包名和類名的組合,

例如: package lee public class Hello { public static void main(String[] args)4 {

} } 在包lee下定義了一個簡單的Java類 使用如下命令則可以在當前路徑下儲存這個檔案(包) 格式:javac -d . Hello.java -d 選項用於設定編譯生成的class檔案的儲存位置,這裡指定將class儲存在當前路徑下(. 就是當前路徑)

import關鍵字:

  • 作用:可以向某個java檔案中匯入指定包層次下某個類或者全部類。import應出現在package之後,Java可以包含多個import語句。
  • 用法: 單個類:import package.subpackage…ClassName; 全部類:import package.subpackage…*; *代表類。 有時候import並不是萬能的如果你在導倆個不同包裡的某個類 但是這倆個類具有相同的名稱 系統就會搞糊塗!!! 這時候就需要使用類的全名。

深入構造器: 前面說了構造器的用於建立例項時 執行初始化。 如果類裡沒有構造器 系統就會預設一個空的構造器 簡而言之 Java類裡至少包含一個構造器 ,你也可以手動自定義構造器用於對成員變數的初始化。(通過new呼叫) 你也可以建立多個構造器 (構造器過載)

java 面向物件思想一部分如上