JAVA基礎課程(四)
二維數組:
數據類型[] [] 數組名 = new 數據類型[m][n] ;
m:代表當前二維數組中有多少個一維數組
n:代表每一個一維數組中的長度
定義的方式還有以下兩種情況
數據類型[] 數組名[] = new 數據類型[m][n]
數據類型 數組名[][] = new 數據類型[m][n]
做些需求 要註意定義的具體 類型:
int x;
int x,y ;
int[] x ;
int [] x,y[] ;
二維數組定義的第二種格式:
數據類型[][] 數組名 = new 數據類型[m][] ; 只給定有m個一維數組,每一個一維數組長度動態給定
二維數組的格式3
靜態初始化
數據類型[][] 數組名稱 = {{元素1,元素2,元素3},{....}} ;
(二)代碼塊
關於代碼塊的概述:
用{}括起來的代碼,統稱為代碼;
根據其位置以及聲明不同:分為以下:
局部代碼塊: 在main()裏面,給變量限定它的生命周期
構造代碼塊:在一個類中的成員位置中,用{}括起來,
作用:可以將多個構造方法中的相同的代碼放到構造代碼塊中,對對象進行初始化. 在每次執行構造方法之前,先執行構造代碼塊.
靜態代碼塊:在一個類的成員位置,也是用{}包起來,但是他被static修飾
作用:一般情況 它的作用給類進行初始化
註意:靜態代碼:只能執行一次
(三)final關鍵字
方法重寫:
由於子類繼承父類的時候,提供一摸一樣的方法聲明,然後會將父類該方法覆蓋掉(重寫,復寫)
有時候(具體的需求),不需要子類重寫父類的功能,針對這種情況,Java提供了一個關鍵字:final 最終的,終態的意思
final:表示最終,終態(不能被更改的)
它可以修飾類,那麽該類不能繼承
它可以修飾成員方法,成員方法不能被重寫
它可以修飾變量,此時這個變量是一個常量
常量的分類: 字面值常量: 字符串常量,字符常量,,,, 自定義常量(final修飾的) pubic final int num = 100 ; final不僅可以修飾基本數據類型 還可以引用類型 如果final修飾的是一個基本數據類型:基本數據類型的值不能再改變了... 如果final習俗的是一個引用類型數據:引用類型的地址值不能再改變了,但是堆內存中的成員變量的值可以變得
final的初始化時機:
1)被final只能被賦值一次(final int a = 10 )
final int a ;
//在使用之前進行初始化,賦值(在構造方法之前賦值) (非靜態的...)
(四)多態
在同一個時刻,體現出來的不同狀態;
水:
固態 氣態 液態
貓狗案例的,創建貓的對象
Cat c = new Cat() ; 貓是貓
Animal a = new Cat() ;貓屬於動物
多態的前提:
1)必須有繼承關系
子類繼承父類,存在一些特點
2)必須有方法重寫
子類繼承父類,方法重寫的目的,舉例:動物吃的方法,每一個具體動物吃的東西不一樣,所有必須要方法覆蓋
3)就是必須有父類的引用指向子類對象 (向上轉型)
父類名 fu = new 子類名() ;
通過父類對象的創建是通過子類在堆內存新建了了一個對象,由於子類又繼承了父類,
父類的引用(初始化)是通過子類新建對象進行的..
多態中的成員訪問特點:
1)成員變量: 編譯看左,運行看左...
2)成員方法(非靜態): 編譯看左,運行看右(存在方法重寫)
3)構造方法:構造方法(無論子類,還是父類),都是對對象進行初始化
4)靜態成員方法: 編譯看左,運行看左(靜態跟類有關系,算不上方法重寫)
多態的好處:
可以提供代碼的復用性:繼承保證
可以提高的代碼的擴展性:由多態保證... (父類的引用指向子類對象)
多態的弊端:
父類引用指向子類對象,
通過父類的引用調用子類特有功能,不能調用....
不能訪問子類特有功能
Father3 f = new Son3()f ; 父類的引用指向子類對象 (向上轉型)
可不可以將子類的引用指父類的引用呢? (向下轉型)
Son s=(Son) f;將父類的引用強制轉換子類的引用
將父類的引用強制轉換子類的引用 ,向下轉型使用不當,會出現一個異常:屬於運行時期異常:ClassCastException
**(五)繼承**
(1)將多個類抽取位一個獨立的類,讓獨立的類和多個類產生繼承關系
繼承 的關鍵字:extends
格式:
class 父類名{
}
class 子類名 extends 父類名{
...
}
繼承 的好處:
1)提供了代碼復用性,解決了代碼的臃腫
2)它是多態的前提(多態的前提是必須有繼承關系)
繼承的特點:
子類繼承父類,是繼承了父類所有的東西(成員變量,成員方法,包括私有),但是子類不能使用私有的東西,只能通過父類的公共的訪問間接的
讓子類訪問它.
(2)繼承的另外一個特點:
在Java中,繼承只支持單繼承,不支持多繼承(子類名 extends 父類名1,父類名2,...)
但是,Java是可以支持多層繼承...
類和類之間的關系:繼承關系
類和接口之間的關系:實現關系
(3)繼承中的註意事項:
1)構造方法不能被繼承,但是通過super關鍵字去訪問
2)私有的可以間接的去訪問
3)什麽時候使用extends?
繼承體現的是一種"is a"的關系:
如果A是B的一種或者B是A的一種,這個可以使用繼承!
不要隨意的使用繼承,只要有"is a"的關系就使用它..
Java開發設計原則:
低耦合,高內聚
耦合:類和類之間的關系 ,盡量降低耦合性
內聚:指的是做一件事情能力(盡量使用一個類完成的事情不要多個類去完成..
在繼承中,成員變量的名稱問題
當前子類繼承父類的時候,子類和父類中的成員變量名稱不一致的情況,非常簡單,分別輸出就可以了;
當子類和父類中的成員變量名稱一致的情況:
1)先到子類的局部位置找,如果找到了,就輸出
2)沒有找到,到子類的成員位置找,有就輸出,
3)在類的成員位置還沒有找到,直接父類的成員位置找,有就輸出
4)如果還沒有,就保存了,不存在這個變量
(4)super關鍵字
要訪問這個子類的局部位置的變量,直接可以訪問.
需求:要訪問Son類的成員位置的這個變量nun,如何訪問
需求:要訪問Father類的成員位置的變量nun.如何訪問?
Java提供了關鍵字:super:代表的父類的空間標識(父類的引用或父類的對象)
this和super關鍵字的用法:
成員變量:
this:
this.成員變量; (訪問當前類)
super:
super.成員變量;(訪問父類)
構造方法:
this(); //無參構造
this("") ;//訪問當前類的有參構造
super()://訪問的父類的無參構造
super("")://訪問的是父類的有參構造..
成員方法:
this.xx()
super.xx()
(5) 關於繼承的成員的問題
構造方法:
子類繼承父類,都會默認的訪問父類的無參構造方法
為什麽呢?
假設數據還沒有被初始化完畢,所以應該先讓父類進行初始化,然後在讓子類初始化--->分層初始化
如果父類的無參構造沒有提供?怎麽辦?
肯定報錯;
如何解決:
1)可以將父類的無參構造提供出來
2)可以super關鍵字去訪問父類的帶參構造...
3)還可以在子類中通過this(),訪問本類中的有參構造,間接的去訪問父類帶參構造
子類的構造方法必須有一個(有參構造/無參構造),讓父類進行初始化
(6) 繼承中成員方法的問題
子類繼承父類,訪問成員方法名不一致的情況,分別調用!
當子類中的成員方名和父類中的成員方法名一致的情況:
1)現在子類的成員位置找,如果有就調用
2)如果沒有找到,在父類的成員位置找,有就調用
(7)關於繼承的用法:
父類中被private修飾的,是可以繼承,但是只能間接的去訪問私有的..
父類被private修飾 成員屬性,子類不不能直接訪問的
子類不能繼承父類的構造方法,但是可以通過super
** (六)抽象類**
(1) 抽象類的概念:
針對一個事物,比如:動物類---->總體概括,之前定一個具體的動物(---->必須給他的某個功能只是聲明即可),只有,貓或者狗等等這些才是具體事物
Java中,如果一個類中有一個方法聲明(抽象方法)抽象功能,那麽這個類定義為抽象類
關鍵字:abstract 抽象的意思
抽象類的特點:抽象類不能直接實例化!(不能創建對象) 接口也不能實例化
關於抽象類:
1)如果一個類中有抽象方法,那麽這個類是一定是一個抽象類
2)抽象類必須有抽象方法嗎? 抽象類中不一定都是抽象方法
抽象類的子類
1)如果子類是抽象類,沒有意義,因為都不能實例化,對象如何創建
2)子類具體類,那麽子類必須實現父類中的抽象功能.
(2) 抽象類的成員特點:
成員變量:
可以是變量,也是一個常量
構造方法:可以有無參,可以有有參,作用:給對象進行初始化的.
成員方法:可以有抽象方法,還可以有非抽象方法...
abstract和哪些關鍵字是沖突的,不能共有!
abstract 和private
abstract 和final
abstract和static
(七)接口
接口:體現的是事務的擴展×××(額外動作,後天經過學習等等)
(1)接口格式(標識符:類,接口:見名知意)
interface 接口名{
//抽象功能
public abstract void jump() ;
}
接口的特點:不能實例化
接口的子實現類:實現類 (具體的實現類)
class 類名+impl implements 接口名{
}
接口的子類如果是抽象類:沒有意義,不能實例化
接口多態(最多)
抽象類多態(比較多)
具體對象的創建(經常會使用)
(2)接口成員的特點:
成員變量:是一個常量,不能更改,並且默認的修飾符
public static final:
構造方法:接口不存在構造方法
成員方法:都是抽象方法
默認的修飾符:public abstract
(八內部類
實際開發中,接口作為形式參數的問題
如果形式參數是接口:
傳統的方式: 1)提供給接口的子實現類
2)內部類的方式(不需要提供子實現類)
(1) 定義:
在B類內部定義A類,A類就屬於B的內部類
內部類訪問外部類的特點:
它可以直接訪問外部了的成員,包括私有
格式:外部類名.內部類名 對象名 = 外部類對象.內部類對象
外部類如何訪問內部類的成員?
通過創建內部類對象的方式間接訪問...
(2) 內部類的分類:
成員內部類:在外部類的成員位置
可以直接外部類的成員,包括私有
外部類要訪問內部類(非靜態的內部類)的成員方法:
格式:外部類名.內部類名 對象名 = 外部類對象.內部類對象
關於成員內部類的修飾符:
private: 作用:保證數據的安全性!
static修飾:可以把靜態內部類看成是外部類的成員.
特點:
靜態成員內部類訪問外部類的數據,該數據必須static修飾
局部內部類:在外部類的局部位置
可以訪問外部類的成員包括私有...
在外部類的局部位置去訪問內部類的show(),需要在局部位置創建內部了對象,通過對象去訪問
匿名內部類
前提是有一個類或者接口
這個類可以是具體類也可以是抽象類
new 類名或者接口名{
方法重寫();
}
匿名內部類的本質:
是繼承了該類或者實現了該接口子類對象...
**(九)形式參數與返回值**
(1) 形式參數的問題:
形式參數是基本類型,對實際參數沒有影響(簡單)
形式參數是引用類型:
類(普通類)
抽象類
- 引用類型:是一個抽象類
- 形式參數是一個抽象類:此時這塊需要的是該抽象類的子類對象 (抽象類多態...)
-
*/
//抽象的Person類
abstract class Person{
public void teach() {
System.out.println("今天天氣不錯,適合踢球...");
}
}
class PersonDemo{
public void method(Person p) { //不能直接創建對象 Person p =new Person(); 可以采用抽象類多態的形式實現
p.teach();
}
}
//需要提供Pereson類的子類
class Teacher extends Person{
}
//測試類
public class TeacherTest {
public static void main(String[] args) {
//需求:需要調用PersonDemo類中的method()方法
//創建PersonDemo對象
PersonDemo pd = new PersonDemo() ;
// Perosn p = new Person() ; //錯誤的,抽象類是不能實例化的
//可以通過子類進行實例化
Person p = new Teacher();
pd.method(p);
}
}
接口
形式參數是一個接口:
//定義一個接口
interface Inter{
public abstract void study() ;
}
class InterDemo{
public void show(Inter i) { //需要創建該接口對象,不能直接實例化 Inter i = new Inter() ;錯誤的
//需要提供接口的子實現類,可以通過子實現類進行實例化:接口多態...
i.study();
}
}
//子實現類
class Student2 implements Inter{
@Override
public void study() {
System.out.println("Good Good Study ,Day Day Up ...");
}
}
//測試類
public class StudentTest {``
public static void main(String[] args) {
//需求:需要調用InterDemo這個了中的show()方法,如何調用
//創建InterDemo類的對象
InterDemo id = new InterDemo() ;
//接口多態的形式創建Inter對象
Inter i = new Student2() ;
id.show(i);
/*Inter i2 = new Inter() {
@Override
public void study() {
//實際開發中要比第一種多
}
};*/
}
}
(2)返回值:
如果返回值基本類型:用對應的基本類型去接收數據即可!
引用類型:
類(具體類): 需要的是該類的對象
抽象類
接口
JAVA基礎課程(四)