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 面向物件思想一部分如上