/* 類的繼承 類的繼承可以簡化類的定義
java只支持單繼承,不允許多重繼承
可以有多層繼承,即一個類可以繼承其一個類的子類,如類B繼承了類A,類C又可以繼承類B
那麼類C也間接繼承了類A
子類繼承父類所有的成員變量和成員方法,但不繼承父類的構造方法,
在子類的構造方法中可使用語句super(參數列表)
調用父類的構造方法
如果子類的構造方法中沒有顯式地調用父類構造方法,也沒用使用this關鍵字調用重載的其它構造方法,則在產生子類的實例對象時
系統默認調用父類無參數的構造方法
子類對象的實例化過程
1 分配成員變量的存儲空間並進行默認的初始化,就是用new關鍵字產生對象後
對類中的成員變量按第三章的表3.1的對應關係對對象中的成員變量進行初始化賦值
2 綁定構造方法參數,就是new Person(實際參數列表)中所傳遞進的參數賦值給構造方中的形式參數變量
3 如果有this()調用,則調用相應的重載構造方法(被調用的重載構造方法又從步驟2開始執行這些流程)
被調用的重載構造方法的執行流程結束後,回到當前構造方法,當前構造方法直接跳轉到步聚6執行
4 顯示或隱式追溯調用父類的構造方法(一直到Ojbect類爲止,Object是所有java類的最頂層父類)
在本音後面部分有詳細講解,父類的構造方法又從步驟2開始對父類執行這些流程,父類的構造方法的執行流程結束後,回到當前構造方法,當前構造方法繼承往下執行
5 進行實例變量的顯示初始化扣喺,也就是執行在定義成員變量時就對其進行賦值的語句
6 執行當前構造方法的方式體中的程序代碼
1):爲什麼super()和this()調用語句不能同時在一個構造函數中出現?
因爲當在一個構造函函數中出現this()調用以後,那麼去別外一個構造函數將也會直接默認或指定的super()方法
如要執行完成以後,返回到初始的構造函數還讓執行super()方法時,那就又是重複操作了,無意義
所以編譯也不會通過的
2):爲什麼super()和this()調用語句只能作爲構造函數的第一句出現
如果不是作爲第一句出現,編譯也會出錯的
如果選執行一些賦值語句,然後執行this或super()函數
那麼就跟我們的執行流程相矛盾了
因爲構造函數需要需要執執行this,如果沒有this執行super()方法
編譯器也不會讓通過的
覆蓋父類的方法
覆蓋方法必須和被覆蓋方法具有相同的方法名稱,參數列表和返回值類型
如果在子類中想調用父類中那個被覆蓋的方法,我們可以用super方法的格式
覆蓋方法時,不能使用此父類中被覆蓋的方法更嚴格的訪問權限
final關鍵字
1 在java中聲明類,屬性和方法時,可以使用關鍵字final來修飾
2 final標記的類不能被繼承
3 final標記的方法不能被子類重寫
4 final標記的變量(成員變量或局部變量)即成爲常量,只能賦值一次
5 方法中定義的內置類只能訪問該方法內的final類型的局部變量
用final定義的局部變量相當於是一個常量,它的生命週期超出了方法運行的重命週期
將一個行參定義成final也是可以的,這就是限定了我們在方法中修改形式參數的值
6 public static final共同標記常量時,這個常量就成了全局常量
抽象類 java中可以定義一些不含方法體的方法,它的方法體的實現交給該類的子類根據自己的情況去實現
這樣的方法就是抽象方法,包含抽象方法的類叫做抽象類
1 抽象類必須使用abstract關鍵字來修飾,抽象方法也必須用abstract來修飾
2 抽象類不能被實例化,也就是不能用new關鍵字去產生對象
3 抽象類只需聲明,而不需實現
4 含有抽象方法的類必須聲明爲抽象類,抽象類的子類必須覆蓋所有抽象方法後才能被實例化,否則這個子類還是個抽象類
*/ //final class Person 將不能被繼承了
class
Person { //protected final String name = "unknown"; 變量爲final時將不能被子類賦值了
protected
String name = "unknown" ;
//public final String x = "abc"; //第一種賦值是初始賦值
public
final String x;
//public static final String x;
public
static final
String y = "abc" ;
public
int age = - 1 ;
public
Person() {
this .x =
"cde" ; }
public
Person(String name, int
age) {
this .name = name;
this .age = age;
//或者在構造函數中進行賦值
this .x =
"abc" ; }
//public void getInfo(){} 將不能在子類重寫了
public
void getInfo()
{
//this.x = "abc"; //用final定義的變量將不能被修改了
System.out.println( "name:" +name+ ", age:" +age);
}
}; class
Student extends
Person { public
String school = "unknown" ;
public
Student() {
//super("xlc",15);
super ();
}
public
Student(String name, int
age, String school) {
this (name,age);
//調用自己的構造函數 this .school = school;
//this(name,age); //調用自己的構造函數
}
public
Student(String name, int
age) {
super (name, age);
}
public
void getInfo()
{
System.out.println( "school:" +school+ "name:" +name+ ",
age:" +age); super .getInfo();
}
public
void study() {
}
}; class
TestStudent { public
static void
main(String[] args) {
//Student st = new Student();
//st.name = "xlc";
//st.age = 34;
//st.getInfo();
Student st =
new Student( "xlc" , 22 , "清華大學" );
st.getInfo();
System.out.println(Float.MAX_VALUE);
}
}; |
/* 接口(interface)
如果一個抽象類中的所有方法都是抽象的,我們就可以將這個類用另外一種方式來定義,也就是接口定義
接口是抽象方法和常量值的定義的集合,從本質上講,接口是一種特殊的抽象類
這種抽象類中只包含常量和方法的定義,而沒有變量和方法的實現
1 接口中的成員都是public訪問類型的,接口的變量默認是用public static final標識的
2 我們可以定義一個新的接口用extends 關鍵字去繼承一個已有的接口
3 我們也可以定義一個類用implements關鍵字去實現一個接口中的所有方法,我們還可以去定義一個抽旬類用implements關鍵字去實現一個接口中定義的部分方法
4 一個類可以繼承一個父類的同時,實現一個或多個接口,extneds關鍵字必須位於implements關鍵字之前
對象的類型轉換
1 子類對象可以自動轉換成父類
2 父類轉換爲子類必須使用強制轉換
3 instanceof操作符可以用它來判斷一個實例對象是否屬於一個類
4 Object類及equals方法
*/ /*abstract class A
{ abstract int aa(int x, int y);
//抽象類將不能實例化
}; class B extends A
{ int aa(int x, int y)
{
return 1;
}
};*/ interface
Runner { int
ID = 1 ;
void
run(); } interface
Animal extends
Runner { void
breathe(); } class
Fish implements
Animal { public
void run() {
System.out.println( "fish is swimming" );
}
//public void breathe()
public
void breathe()
{
System.out.println( "fish is bubbling" );
}
public
static void
main(String[] args) {
Fish f =
new Fish();
int
j= 0 ;
j = Runner.ID;
j = f.ID;
//f.ID = 2; //常量不能被賦值
}
}; abstract
class LandAnimal
implements Animal
{ public
void breathe()
{
}
}; interface
dog { void
uaau(); } interface
Flyer { void
fly(); } class
Bird implements
Runner, Flyer { public
void run() {
}
public
void fly() {
}
}; //繼承一個類時,可以實現其它接口
//也是可以繼承從外接口類的
class
Student extends
Person implements
Runner, dog //如果繼承類和接口,extends必須在implements之前
{ public
void run() {
}
public
void uaau() {
}
}; interface
A { //public static final int ID=1;
//int ID = 1; //這個是一個常量而不是一個變量,接口只能定義常量,不能定義變量,
//只能定義常量和抽象類
public
static final
int ID= 1 ;
int
aa( int
x, int y);
void
bb(); } /*class
{ public static void main(String[] args)
{
System.out.println("Hello World!");
}
}*/ |
/* 面向對象的多態性
1):應用程序不必爲每一個派生類(子類)編寫功能調用
只需要對抽象基類進行處理即可,這一招叫"以不變應萬變",可以大大提高程序的可複用性
2):派生類的功能可以被基類的引用變量引用,這叫向後兼容,可提高程序的可擴充性和可維護性
以前寫的程序可以被後來程序調用不足以爲奇,現在寫的程序(如callA方法)能調用以後寫的程序(以後編寫的一個類A的子類,如類D)就了不起了
*/ class
A { public
void func1() {
System.out.println( "A func1 is calling" );
}
public
void func2() {
func1();
}
}; class
B extends A
{ public
void func1() {
System.out.println( "B func1 is calling" );
}
public
void func3() {
System.out.println( "B func3 is calling" );
}
}; class
C { public
static void
main(String[] args) {
B b =
new B();
callA(b);
//A aa = b;
//callA(new A());
}
public
static void
callA(A a) {
/*if(a instanceof B)
{
B b = (B)a; //強制類型轉換
b.func1();
b.func2();
b.func3();
}else{
a.func1();
a.func2();
}*/ a.func1();
a.func2();
//a.func1();
//a.func2();
//a.func3();
}
}; class
Student extends
Object { private
String name; private
int age; public
Student(String name, int
age) {
this .name = name;
this .age = age;
}
/*public boolean equals(Object obj)
{
Student st = null;
if(obj instanceof Student)
{
st = (Student)obj;
if(st.name == name && st.age == age)
{
return true;
} else{
return false;
}
}else{
return false;
}
}*/ //如果沒有覆蓋父類的equals方法,那麼將返回不等
//只是重載了一下函數
public
static void
main(String[] args) {
Student st1 =
new Student( "張三" , 20 );
Student st2 =
new Student( "張三" , 20 );
if (st1.equals(st2))
{
System.out.println( "相等" );
} else {
System.out.println( "不相等" );
}
}
}; /*class
{ public static void main(String[] args)
{
System.out.println("Hello World!");
}
}*/ |
interface
PCI { void
start(); void
stop(); } class
NetWrokCard implements
PCI { public
void start() {
System.out.println( "Send..." );
}
public
void stop() {
System.out.println( "stop..." );
}
}; class
SoundCard implements
PCI { public
void start() {
System.out.println( "du..." );
}
public
void stop() {
System.out.println( "sound stop..." );
}
}; class
MainBoard { public
void usePCICard(PCI p)
{
p.start();
p.stop();
}
}; class
Assembler { public
static void
main(String[] args) {
MainBoard mb =
new MainBoard();
NetWrokCard nc =
new NetWrokCard();
SoundCard sc =
new SoundCard();
mb.usePCICard(nc);
mb.usePCICard(sc);
//匿名類
/*mb.usePCICard(
new PCI()
{
public void start()
{
System.out.println("test start...");
}
public void stop()
{
System.out.println("test end...");
}
}
);*/ //類擬於
class
A implements
PCI {
public
void start() {
System.out.println( "test start..." );
}
public
void stop() {
System.out.println( "test end..." );
}
};
mb.usePCICard( new
A()); }
}; |