18,多態
多態:可以理解爲事物存在的多種體現形態。
1,多態的體現。
父類的引用指向了自己子類對象。
父類的引用也可以接收自己的子類的對象。
2,多態的前提。
必須是類與類之間有關係,要麼繼承,要麼實現。
存在覆蓋
3,多態的好處。
多態的出現大大提高了程序的擴展性。
4,弊端
提高了擴展性,但是隻能使用父類的引用訪問父類中的成員。
5,多態的應用。
轉型:
Cat類中有一個特有的方法CatchMouse();
Animal a=new Cat();//類型提升。向上轉型
a.eat();
//如果想要調用子類特有的方法時,如何操作?
//強制將父類的引用。轉成子類類型.向下轉型。
//我們能轉換的是父類引用指向了自己的子類對象時,該應用可以被提升,也可以被強制轉換。
//多態自始自終都是子類對象在做着變化。
Car c=(Car)a;
c.catchMouse();
判斷某一類型 引用指向的對象到底符合什麼類型的時候
if(a instanceof Cat){
Cat c=(Cat)a;
c.catchMouse();
}
6,成員特點。
在編譯時期:參閱引用型變量所屬的類中是否有調用德爾方法。如果有,編譯通過,沒有編譯失敗。
在運行時期:參閱對象所屬的類中是否有調用的方法。
簡單總結就是:成員函數在多態調用時,編譯看左邊,運行看右邊。
在多態中,成員變量的特點:(非靜態的)
無論編譯和運行,都參考左邊。(引用型變量所屬的類)
父類有一個變量num,子類有一個變量num
Fu f=new Zi();
f.num是父類中的num;
Zi zi=new ZI();
zi.num是子類中的num;
在多態中靜態成員函數的特點:
無論編譯和運行,都參考左邊。
類加載到內存,靜態就存在了,不需要對象。
19,Object :是所有對象的直接或者間接父類,傳說的上帝。
該類中定義的肯定是所有對象都具備的功能。
Object 類中已經提供了對對象是否相同的比較方法。
如果自定義類中也有比較相同的功能,沒有必要重新定義。
如果沿襲父類中的功能,建立自己特有比較內容即可。這就是覆蓋。
equals(); toString();
20,內部類
將一個類定義在另一個類的裏面,對裏面那個類就稱爲內部類(內置類,嵌套類)。
內部類與外部類的訪問規則
/*
* 內部類的訪問規則
* 1,內部類可以直接訪問外部類中的成員,包括私有
* 之所以可以直接訪問外部類的成員,是因爲內部類中持有了外部類的引用。外部類.this
* 2,外部類要訪問內部類,必須建立內部類對象。
*/
public class InnerClassDemo {
public static void main(String[] args) {
// Outer o=new Outer();
// o.method();
// 直接訪問內部類的成員。
Outer.Iner in = new Outer().new Iner();
in.function();
}
}
class Outer {
private int x = 3;
// 內部類可以私有化
class Iner {
int x = 4;
public void function() {
int x = 6;
System.out.println("inner" + x);// 這裏打印6,內部有的不往外找了
System.out.println("inner" + this.x);// 這裏打印4;
System.out.println("inner" + Outer.this.x);// 這裏打印6
}
}
public void method() {
Iner i = new Iner();
i.function();
}
}
訪問格式:
1,當內部類定義在外部類的成員位置上,而且非私有的,可以再外部其他類中,可以直接建立內部類對象。
格式:
外部類.內部類名 變量名=外部類對象.內部類對象;
2,當內部類在成員位置上,就可以被成員修飾符所修飾。
比如,private :將內部類在外部類中進行封裝。
static :內部類就具備static 的特性。
當內部類被static 修飾後,只能直接訪問外部類中的static成員了。出現了訪問權限、
在外部其他類中,如何直接訪問static內部類的非靜態成員呢?
new Outer.Inner().function();;
在外部其他類中,如何直接訪問static內部類的靜態成員呢?
Outer.Inner.function();
注意:當內部類中定義了靜態成員,該內部類就必須是static的。
內部類定義規則。
當描述事物時,事物的內部還有事物,該事物用內部類來描述。
因爲內部事物在使用外部事物的內容。
內部類只有定義在成員變量上的時候,才能被私有或者靜態所修飾,一般內部類是不會被公有修飾的。
21,匿名內部類
在方法當中定義內部類
public class InnerClassDemo {
public static void main(String[] args) {
Outer o=new Outer();
o.method(7);
o.method(6);
}
}
/*
* 內部類定義在局部時
* 1,不可以被成員修飾符修飾
* 2,可以直接訪問外部類中的成員,因爲還持有外部類的引用。
* 但是不可以訪問他所在的局部中的變量。只能訪問被final修飾的局部變量
*
*/
class Outer {
int x = 3;
void method(final int a) {
final int y=4;
/**
* 此時不能被靜態私有修飾,因爲修飾符只能修飾成員,現在Inner在局部了,所以不能
* @author Administrator
*/
class Inner {
/**
* 這裏也不能用static修飾
*/
void function() {
System.out.println(Outer.this.x);
System.out.println(y);//加final
System.out.println(a);//加final
}
}
new Inner().function();
}
}
匿名內部類:
1,匿名內部類其實就是內部類的簡寫格式。
2,定義匿名內部類的前提;
內部類必須是繼承一個類或者接口。
3, 匿名內部類的格式,new 父類或者接口(){定義子類的內容}
4 , 其實匿名內部類就是一個匿名子類對象。而且這個對象有點胖,也可以理解爲帶內容的對象。
5,匿名內部類中定義的方法最好不要超過三個。
public class InnerClassDemo {
public static void main(String[] args) {
new Outer().function();
}
}
class Outer {
int x = 3;
/*
* class Inner extends AbsDemo{ void show(){ System.out.println("show:"+x);
* } }
*/
// 對上面的代碼簡化
public void function() {
// new Inner().show();
/*
* 整體是一個對象,是AbsDemo的一個子類對象,只有之類才能複寫方法。
*/
new AbsDemo() {// 匿名內部類
@Override
void show() {// 複寫方法
// TODO Auto-generated method stub
System.out.println("x:" + x);
}
}.show();
}
}
abstract class AbsDemo {
abstract void show();
}
基本小練習
public class InnerClassDemo {
public static void main(String[] args) {
// 類名. 肯定有靜態成員Test.function(),有一個靜態的方法。
// .method;function 這個方法運算後的結果是一個對象,而是一個Inter對象
// 只有Inter才能調用mthod方法。
Test.function().method();
}
}
interface Inter {
void method();
}
class Test {
// 補足代碼。通過匿名內部類
/*
* static class Inner implements Inter{
*
* @Override public void method() { // TODO Auto-generated method stub
* System.out.println("method run"); }
*
* }
*/
static Inter function() {
// return new Inner();
return new Inter() {
@Override
public void method() {
// TODO Auto-generated method stub
System.out.println("method run");
}
};
}
}
關於內部類的概述總結
- //代碼1:內部類對外部類可見
- class Outer{
- //創建私有內部類對象
- public Inner in=new Inner();
- //私有內部類
- private class Inner{
- ...
- }
- }
- //代碼2:外部類對內部類可見
- //(內部類可以訪問外部類的所有成員變量和方法)
- class Outer{
- //外部類私有數據域
- private int data=0;
- //內部類
- class Inner{
- void print(){
- //內部類訪問外部私有數據域
- System.out.println(data);
- }
- }
- }
- package hr.test;
- //代碼3:靜態內部類對外部變量的引用
- public class Outer{
- private static int i=0;
- //創建靜態內部類對象
- public Inner in=new Inner();
- //靜態內部類
- private static class Inner{
- public void print(){
- System.out.println(i); //如果i不是靜態變量,這裏將無法通過編譯
- }
- }
- }
- class Outter{
- public void outMethod(){
- final int beep=0;
- class Inner{
- //使用beep
- }
- Inner in=new Inner();
- }
- }