国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Java編程思想讀書筆記-1(第2-7章)
一.所有對象都必須由你建立
1.    存儲在哪里
1.    寄存器:我們在程序中無法控制
2.    stack:存放基本類型的數(shù)據(jù)和對象的reference,但對象本身不存放在stack中,而是存放在Heap中
3.    Heap:存放用new產(chǎn)生的數(shù)據(jù)
4.    Static storage:存放在對象中用static定義的靜態(tài)成員
5.    Constant storage:存放常量
6.    NON-RAM:硬盤等永久存儲空間
2.    特例:基本型別
基本類型數(shù)據(jù)存放在Stack中,存放的是數(shù)據(jù)。而產(chǎn)生對象時,只把對象的reference存放在stack中,用于指向某個對象,對象本身存放在Heap中。
3.    Java中的數(shù)組
當你產(chǎn)生某個存儲對象的數(shù)組時,真正產(chǎn)生的其實是存儲reference的數(shù)組。引數(shù)組建立后,其中的每一個reference都會被自動設為null,表示“不指向任何對象”。
二.建立新的數(shù)據(jù)型別:Class
1.    數(shù)據(jù)成員和函數(shù)
1.1    基本成員的缺省值
1)    當class的某個成員屬于基本型別時,即使你沒有為它提供初值,Java仍保證它有一個缺省值。
2)    只有當變量身份是“class內的成員時,Java才保證為該變量提供初值。
三.函數(shù)(Mehtods),引數(shù)(arguments),返回值(return values)
1.    引數(shù)列
當引數(shù)傳遞的是對象時,傳遞的是對象的reference。
四.注解用內嵌式文檔
Java提供兩種注解風格:/*XXXX*/、//XXXX
第3章    控制程序流程
一.使用Java運算符
1.關系運算符
1.) 當對兩個對象運用關系運算符進行比較時,比較的是object reference,如:
java/lang/Integer.java/lang/Integer.
java/lang/Integer.java/lang/Integer.
java/lang/System.
結果為false,因為兩個object reference(n1和n2)值是不同的
2) quals()的缺省行為也是拿referenct來比較。不過Java中的class覆寫了equals方法,如:
java/lang/Integer.java/lang/Integer.
java/lang/Integer.java/lang/Integer.java/lang/System.2.    邏輯運算符
1)    只能將and、or、not施用于boolean值身上。如果邏輯運算符兩邊的值存在non-boolean值,將會出錯,如:
int test1 = 1;
java/lang/System.3.    位移運算符
如果所操作的位移對象是char、byte、short,位移動作發(fā)生之前,其值會先被晉升為int,運算結果會是int。
二.流程控制
1.    迭代(iteration)
1.1    逗號運算符
逗號運算符只能用于for循環(huán)的控制表達式中的initialization和step兩部分中,如:for(int i=0, j=I+1; I<5; i++, j=I*2)
1.2    break和continue
break表示退出循環(huán);continue表示退出本次循環(huán),回來循環(huán)起始位置。
1.3    label
label只有放在迭代語句之前才起作用,在label和迭代語句之間插入任何語句都不會起作用。
2.    Switch
switch中的選擇器必須是int或char型,如:
float i = 2;
switch ( i )//將出錯,因為i不是int或char之一
3.    計算細節(jié)
1)    從float或double轉為整數(shù)值,總是以完全舍棄小數(shù)的方式進行。
4.    Math.random()的輸出范圍是[0, 1]。
第4章    初始化和清理
一.以構造函數(shù)(constructor)確保初始化的進行
如果某個class具備構造函數(shù),Java便會在對象生成之際,使用者有能力加以操作之前,自動調用其構造函數(shù),于是便能名確保初始化動作一定被執(zhí)行。
二.函數(shù)重載(Method overloading)
1.    區(qū)分重載函數(shù)
由于只能從函數(shù)名和函數(shù)的引數(shù)列來區(qū)分兩個函數(shù),而重載函數(shù)具有相同的函數(shù)名稱,所以每個重載函數(shù)都必須具備獨一無二的引數(shù)列。
2.    Default構造函數(shù)
1)    default構造函數(shù)是一種不帶任何引數(shù)的構造函數(shù)。如果你所開發(fā)的class不具任何構造函數(shù),編譯器會自動為你生成一個default構造函數(shù)。
2)    如果你自行定義了任何一個構造函數(shù)(不論有無引數(shù)),編譯器就不會為你生成default構造函數(shù)。
3)    如果定義了一個class,如
class Bush{
Bush(int I){}
}
當想用new Bush();來產(chǎn)生class的實例時,會產(chǎn)生錯誤。因為在定義class時已定義了構造函數(shù),所以編譯器就不會為class生成default構造函數(shù)。當我們用new Bush()來產(chǎn)生實例時,會嘗試調用default構造函數(shù),但在class中沒有default構造函數(shù),所以會出錯。如:
class Sundae
{
Sundae(int i) {}
}
public class IceCream
{
public static void main(
java/lang/String.{
//Sundae x = new Sundae();會編譯出錯,無構造函數(shù)Sundae()
Sundae y = new Sundae(1);
}
}
*:在定義一個class時,如果定義了自己的構造函數(shù),最好同時定義一個default構造函數(shù)
3.    關鍵字this
1)    this僅用于函數(shù)之內,能取得“喚起此一函數(shù)“的那個object reference。
2)    在構造函數(shù)中,通過this可以調用同一class中別的構造函數(shù),如
public class Flower{
Flower (int petals){}
Flower(
java/lang/String.Flower(int petals, Sting ss){
//petals++;調用另一個構造函數(shù)的語句必須在最起始的位置
this(petals);
//this(ss);會產(chǎn)生錯誤,因為在一個構造函數(shù)中只能調用一個構造函數(shù)
}
}
**:1)在構造調用另一個構造函數(shù),調用動作必須置于最起始的位置
2)不能在構造函數(shù)以外的任何函數(shù)內調用構造函數(shù)
3)在一個構造函數(shù)內只能調用一個構造函數(shù)
4.    Static的意義
無法在static函數(shù)中調用non-static函數(shù)(反向可行)。為什么不能呢,我們看下面的例子。
例4.2.4.1
假設能在static函數(shù)中調用non-static函數(shù),那么(a)處就將出錯。因為在沒有產(chǎn)生Movie class實例之前,在就不存在Movie class內的name實例,而在getName()中卻要使用name實例,顯然的錯誤的。
class Movie{
java/lang/String.Movie(){}
public Movie(
java/lang/String.public static java/lang/String.}
public class Test{
public static void main(
java/lang/String.//下面兩名先產(chǎn)生實例后再調用getName()沒有問題
//Movie movie1 = new Movie(“movie1”);
//String name1 = movie1.getName();
//下面一名將出錯
//String name2 = Movie.getname(); (a)
}
}
三.清理(cleanup):終結(finalization)與垃圾回收(garbage collection)
1)你的對象可能不會被回收
只有當
程序不夠內存時,垃圾回收器才會啟動去回收不再被使用的對象的內存空間。某個對象所占用的空間可能永遠不會被釋放掉,因為你的程序可能永遠不會逼近內存用完的那一刻,而垃圾回收器完全沒有被啟動以釋放你的對象所占據(jù)的內存,那些空間便會在程序終止時才一次歸還給操作系統(tǒng)
3)    只有在采用原生函數(shù)(native methods)時,才使用finalize()。
四.成員初始化(member initialization)
1)    函數(shù)中的變量不會被自動初始化,如
void f(){
int i;
i++;
}
將發(fā)生編譯錯誤,因為i沒有被初始化。
2)    class的數(shù)據(jù)成員會被自動初始化,具體情況如下(見P220例子):
基本型別:boolean:false、char:null(\u0000)、byte:0、short:0、int:0、
long:0 、float:0、double:0
對象(reference):null
1.    初始化次序
1)    所有變量一定會在任何一個函數(shù)(甚至是構造函數(shù))被調用之前完成初始化(見P233例子)
2)    在產(chǎn)生一個class的對象(包含static成員的class的代碼被裝載)時,首先自動初始化class中的static成員變量,再執(zhí)行所有出現(xiàn)于static數(shù)據(jù)定義處的初始化動作,最后執(zhí)行static block,所有這些初始化操作只在第一次生成該對象時進行。
3)    自動初始化class中的其它成員變量。
4)    執(zhí)行所有出現(xiàn)于數(shù)據(jù)定義處的初始化動作。如:int i=1;的執(zhí)行順序是先把I自動初始化為0,再執(zhí)行數(shù)據(jù)定義處的初始化動作,初始化為1。
5)    執(zhí)行non-static block
6)    調用構造函數(shù)。
例:
class Cup{
Cup(int marker){
java/lang/System.}
void f(int marker){
java/lang/System.}
}
class Cups{
static Cup c1 = new Cup(11);
static Cup c2;
Cup c3 = new Cup(33);
Cup c4;
{
c3 = new Cup(3);
c4 = new Cup(4);
}
static{
c1 = new Cup(1);
c2 = new Cup(2);
}
Cups(){
java/lang/System.}
}
public class ExplicitStatic{
public static void main(
java/lang/String.java/lang/System.Cups.c1.f(99);
}
static Cups x = new Cups();
static Cups y = new Cups();
}
結果為:
Cup(11)
Cup(1)
Cup(2)
Cup(33)
Cup(3)
Cup(4)
Cups()
Cup(33)
Cup(3)
Cup(4)
Cups()
Inside main()
f(99)
2.    Array的初始化
1)    定義數(shù)組時不能指定大小。如int[4] iArr = {0, 1, 2, 3};,由于指定了數(shù)組的大小,會編譯出錯。
2)    數(shù)組只是存放reference的數(shù)組。Array與non-array的結構圖如下:
a)對于基本型別數(shù)據(jù),存放的是數(shù)據(jù)。如
int i = 5;
b)對于class變量,存放的是reference,這個reference指向一個存有class實例的內存空間。如
java/lang/String.變量s存放的是一個reference,這個reference指向一個存有String實例的內存空間。
c)對于基本型別數(shù)組,存放的是reference數(shù)組,數(shù)組中的每一個reference都指向一個class實例的內存空間。如
int[] ia = {10, 11, 12};
數(shù)組ia存放的是一個reference數(shù)組,數(shù)組中的每一個reference都指向一個的int實例的內存空間。
d)對于class數(shù)組,存放的是reference數(shù)組,數(shù)組中的每一個reference都指向一個的class實例的內存空間。如
java/lang/String.數(shù)組sa存放的是一個reference數(shù)組,數(shù)組中的每一個reference都指向一個的String實例的內存空間。
3)    任何數(shù)組都要進行初始化,使用沒有進行初始化的數(shù)組會產(chǎn)生運行時錯誤,如:
int[] iArr;
java/lang/System.數(shù)組初始化可在任何地方,可用以下方法來對數(shù)組進行初始化:
a)    int[] iArr = {1,1,1,1};//數(shù)組的長度為{}元素的個數(shù)
b)    int i = 10;
int[] iArr = new int[i];//數(shù)組的長度可為變量(這在C/C++中不行)
java/lang/System.java/lang/Integer.java/lang/Integer.java/lang/System.I)    對于基本型別數(shù)組,new產(chǎn)生的是用于存放數(shù)據(jù)的數(shù)組;否則,產(chǎn)生的只是存放reference的數(shù)組。
II)    new可用來初始化基本型別的數(shù)組,但不能產(chǎn)生non-array的  基本型別數(shù)據(jù)。
c)    int[] iArr = new int[]{1,1,1,1};
java/lang/Integer.java/lang/Integer.java/lang/Integer.java/lang/Integer.3.    多維數(shù)組(Multidimensional)arrays
多維數(shù)組每一維的大小可以不一樣,如:
java/lang/Integer.a5 = new java/lang/Integer.for(int i=0; i<a5.length; i++)
a5[i] = new 
java/lang/Integer.for(int j=0; j<a5[i].length
a5[i][j] = new 
java/lang/Integer.第5章    隱藏實現(xiàn)細節(jié)
一.Java訪問權限飾詞(access specifiers)
Java有public、protect、friendly、private四種訪問權限,并且這四訪問權限的訪問范圍越來越小。
1.    friendly
1)    果一個class內的數(shù)據(jù)成員或方法沒有任何權限飾詞,那么它的缺省訪問權限就是friendly。同一個package內的其它所有classes都可以訪問friendly成員,但對package以外的classes則形同private。
2)  對于同一個
文件夾下的、沒有用package的classes,Java會自動將這些classes初見為隸屬于該目錄的default package,可以相互調用class中的friendly成員。如以下兩個class分別在同一個文件夾的兩個文件中,雖然沒有引入package,但隸屬于相同的default package。
class Sundae{
//以下兩個方法缺省為friendly
Sundae(){}
java/lang/Void.java/lang/System.}
public class IceCream{
public static void main(
java/lang/String.Sundae x = new Sundae();
x.f();
}
}
2.    public:可以被任何class調用
3.    private:private成員只能在成員所屬的class內被調用,如:
class Sundae{
private Sundae(){}//只能在Sundae class中被調用
Sundae(int i) {}
static Sundae makASundae()    {
return new Sundae();
}
}
public class IceCream{
public static void main(
java/lang/String.// Sundae class中構造函數(shù)Sundae()是private,
// 所以不能用它進行初始化
//Sundae x = new Sundae();
Sundae y = new Sundae(1);//Sundae(int)是friendly,可以在此調用
Sundae z = Sundae.makASundae();
}
}
4.    protected:具有friendly訪問權限的同時,又能被subclass(當然包括子孫類,即子類的子類)所訪問。即,既能被同一package中的classes訪問,又能被protected成員所在class的subclass訪問。
二.Class的訪問權限
1.Class同樣具有public、protect、friendly、private四種訪問訪問權限:
1)public:在任何地方都可被使用
2)protect、private:除了它自己,沒有任何class可以使用,所以class不能是
protected或private(inner class除外)
3)    friendly:同一個package中的classes能用
2.    如何調用構造函數(shù)被聲明為private的class
1)    用static函數(shù)
2)    用Singteton模式
class Soup{
private Soup(){}
//(1)靜態(tài)函數(shù)方法
public static Soup makeSout(){
return new Soup();
}
//(2)The "Singleton" pattern:
private static Soup ps1 = new Soup();
public static Soup access(){
return ps1;
}
public void f(
java/lang/String.java/lang/System.}
}
public class Lunch{
public static void main(
java/lang/String.//Soup priv1 = new Soup();編譯錯誤
Soup priv2 = Soup.makeSout();
Soup priv3 = Soup.access();
priv2.f("priv2");
priv3.f("priv3");
}
第6章    重復運用classes
一.繼承(inheritance)
1.    在derived class中overriding某個函數(shù)時,只能覆寫base class中的接口,即base class中的public或protected或friendly函數(shù)。如果試圖overriding一個private函數(shù),雖然編譯通過,但實際上你只是在derived class中添加了一個函數(shù)。如
class Cleanser{
private void prt(){//(b)
java/lang/System.}
}
public class ExplicitStatic extends Cleanser{
public void prt(){
java/lang/System.}
public static void main(
java/lang/String.Cleanser x = new ExplicitStatic();
x.prt();//(a)
}
}
因為Cleanser中的prt()是private,所以不能在其derived class中被覆寫。ExplicitStatic中的prt()只是ExplicitStatic中的一個函數(shù),所以當試圖在(a)處通過多態(tài)來調用prt()時,會發(fā)生錯誤。如果把(b)處的private去掉,則結果為
ExplicitStatic.prt()
2.    Super的使用
1)通過關鍵字super可以調用當前class的superclass(父類)。
例6.1.1.1
class Base{
Base(){
java/lang/System.public void scrub() { java/lang/System.}
class Cleanser extends Base{
private 
java/lang/String.java/lang/String.public void append(java/lang/String.public void dilute() { append(" dilute()"); }
public void apply() { append(" apply()"); }
public void scrub() { append(" scrub()"); }
public void print() { 
java/lang/System.Cleanser(){
java/lang/System.}
public static void testStatic(){
java/lang/System.}
public static void main(
java/lang/String.Cleanser x = new Cleanser();
x.dilute(); x.apply(); x.scrub(); x.print();
}
}
public class ExplicitStatic extends Cleanser{
ExplicitStatic(){
java/lang/System.}
public void scrub(){
append(" Detergen.scrub()");
super.testStatic();
super.scrub();//調用的是Cleanser.scrub()
}
public void foam() { append(" foam()"); }
public static void main(
java/lang/String.ExplicitStatic x = new ExplicitStatic();
x.dilute(); x.apply(); x.scrub(); x.foam();
x.print(); 
java/lang/System.Cleanser.main(args);
testStatic();
}
}
運行結果:
Base()
Cleanser(): Cleanser
ExplicitStatic()
testStatic()
Cleanser dilute() apply() Detergen.scrub() scrub() foam()
Test base class:
Base()
Cleanser(): Cleanser
Cleanser dilute() apply() scrub()
testStatic()
2)通過super來調用superclass中的成員時,調用的是最近成員。
例6.1.1.2
class Base{
protected 
java/lang/String.//private String baseS = "Base";
Base(){
java/lang/System.}
class Cleanser extends Base{
protected 
java/lang/String.public java/lang/String.java/lang/String.Cleanser(){
java/lang/System.}
Cleanser(
java/lang/String.java/lang/System.}
}
public class ExplicitStatic extends Cleanser{
java/lang/String.java/lang/String.ExplicitStatic(){
super("ExplicitStatic");
java/lang/System.+ baseS + "super.baseS = " + super.baseS);
baseS = "ExplicitStatic";
java/lang/System.}
public static void main(
java/lang/String.ExplicitStatic x = new ExplicitStatic();
}
}
結果1:
Base()
Cleanser(ExplicitStatic): s = Cleanser
ExplicitStatic():s2 = Cleanser, baseS = Cleanser,super.baseS = Cleanser
baseS = ExplicitStatic , super.baseS = Cleanser
在上面例子中,在三個class中都存在String bases實例。在ExplicitStatic中如果直接調用baseS,則實際調用的是當前類ExplicitStatic中的baseS(即(c)處的成員);如果通過super.bases來調用baseS,則調用的是離當前類ExplicitStatic最近的baseS成員,即Cleanser class中的baseS實例(即(b)處),產(chǎn)生的結果如結果1所示。如果把(b)處語句注釋掉,則將調用Base class中的baseS,結果如結果2所示。
結果2:
Base()
Cleanser(ExplicitStatic): s = Cleanser
ExplicitStatic():s2 = Cleanser, baseS = Base,super.baseS = Base
baseS = ExplicitStatic , super.baseS = Base
3.    Base class的初始化
2.1    當你產(chǎn)生derived class對象時,其中會包含base class子對象(subobject)。這個子對象就和你另外產(chǎn)生的base class對象一模一樣。
2.2    通過super()可調用base class的構造函數(shù),但必須放在構造函數(shù)的第一行,并且只能在構造函數(shù)中運用。
2.3    初始化順序為:
1)    加載代碼(.class
文件
2)    初始化class的靜態(tài)成員,初始化順序了“從里到外”,即從base class開始。
3)    在derived class的構造函數(shù)中調用base class的構造函數(shù)。
如果在derived class的構造函數(shù)中沒有通過super()顯式調用調用base class的構造函數(shù),編譯器會調用bass class的default構造函數(shù)并自動生成相應的調用語句,從而產(chǎn)生一個base class實例。如果在derived class的構造函數(shù)中通過super()顯示調用了父類的構造函數(shù),則調用所指定的構造函數(shù)。調用構造函數(shù)的調用順序是“從里到外”。
4)    調用derived class的構造函數(shù)。
**:當base class沒有default構造函數(shù)時,必須在derived class的構造函數(shù)中通過super顯示調用base class的構造函數(shù)。
例:下面代碼的初始化過程為:
1)    裝載ExplicitStatic的代碼(裝載ExplicitStatic.class文件)。
2)    發(fā)現(xiàn)ExplicitStatic有關鍵字extends,裝載ExplicitStatic的base class的代碼(裝載Cleanser.class文件)。
3)    發(fā)現(xiàn)Cleanser有關鍵字extends,裝載Cleanser的base class的代碼(裝載Base.class文件)。
4)    初始化Base class中的靜態(tài)成員。
5)    初始化Cleanser class中的靜態(tài)成員。
6)    初始化ExplicitStatic class中的靜態(tài)成員。
如果把(c)處的代碼注釋掉,那么初始化工作到此就結束了。
7)    為ExplicitStatic對象分配存儲空間,并把存儲空間初始化為0。
8)    在ExplicitStatic class的構造中調用super("ExplicitStatic")(在ExplicitStatic class的構造函數(shù)中顯式調用父類的構造函數(shù)),試圖產(chǎn)生一個Cleanser class實例。
9)    為Cleanser對象分配存儲空間,并把存儲空間初始化為0。
10)    由于Cleanser class又是繼承自Base class,會在Cleanser class的構造函數(shù)中通過super()(由于沒有顯式調用父類的構造函數(shù),所以自動調用父類的default構造函數(shù))調用父類的構造函數(shù),試圖產(chǎn)生一個Cleanser class實例。
11)    產(chǎn)生一個Base class實例。先初始化成員變量,再調用構造函數(shù)。
12)    回到Cleanser class,產(chǎn)生一個實例。首先初始化Cleanser class中的成員數(shù)據(jù),再執(zhí)行構造函數(shù)Cleanser(String a)中的其余部分。
13)    回到ExplicitStatic class,產(chǎn)生一個實例。首先初始化ExplicitStatic class中的成員數(shù)據(jù),再執(zhí)行構造函數(shù)ExplicitStatic ()中的其余部分(System.out.println(“ExplicitStatic()”))。
class Base{
static int s1 = prt("s1 initialized.", 11);
int i1 = prt("i1 initialized.", 12);
Base(){
java/lang/System.java/lang/System.draw();//(d)
}
void draw(){
java/lang/System.}
static int prt(
java/lang/String.java/lang/System.return num;
}
}
class Cleanser extends Base{
static int s2 = prt("s2 initialized.", 21);
int i2 = prt("i2 initialized.", 22);
Cleanser(){
java/lang/System.java/lang/System.}
Cleanser(
java/lang/String.//super();(b)
java/lang/System.java/lang/System.}
void draw(){
java/lang/System.}
}
public class ExplicitStatic extends Cleanser{
static int s3 = prt("s3 initialized.", 31);
int i3 = prt("i3 initialized", 31);
ExplicitStatic(){
super("ExplicitStatic");//(a)
java/lang/System.java/lang/System.}
public static void main(
java/lang/String.ExplicitStatic x = new ExplicitStatic();//(c)
}
}
結果:
s1 initialized.
s2 initialized.
s3 initialized.
//如果把(c)處的代碼注釋掉,輸出結果到此為止,不會輸出下面結果
i1 initialized.
Base()
s1 = 11 ,i1 = 12
Cleanser.draw:s2 = 21 ,i2 = 0//(d)處結果
i2 initialized.
Cleanser(ExplicitStatic)//(a)處結果
s2 = 21 ,i2 = 22
i3 initialized
ExplicitStatic()
s3 = 31 ,i3 = 31
由于在Base()中調用draw()時,Cleanser中的i2還未進行初始化,而在為Cleanser對象分配存儲空間時,把存儲空間初始化為0,所以此時i2為0。
2.4    代碼及結果中的(a)說明了是先產(chǎn)生當前class的base class的實例,否則在derived class中無法調用base class的成員。在調用Cleanser class的構造函數(shù)Cleanser(String a)時,在Cleanser(String a)中沒有用super顯式調用Base class的構造函數(shù),所以
系統(tǒng)會自動生成調用Base class的default構造函數(shù)的語句,如(b)。
4.    組合與繼承之間的快擇
.    1)繼承表示的是一種“is-a(是一個)”的關系,如貨車是汽車中的一種;組合表示的是一種“has-a(有一個)”的關系,如汽車有四個輪子。
2)是否需要將新的class向上轉型為base class。
5.    在繼承中的訪問權限
protect變量能被子孫類所調用。如Base class中的baseS能被Cleanser class和ExplicitStatic class調用。
class Base{
protected java/lang/String.//private String baseS = "Base";
Base(){
java/lang/System.}
class Cleanser extends Base{
protected 
java/lang/String.public java/lang/String.java/lang/String.Cleanser(){
java/lang/System.}
Cleanser(
java/lang/String.java/lang/System.}
}
public class ExplicitStatic extends Cleanser{
java/lang/String.java/lang/String.ExplicitStatic(){
super("ExplicitStatic");
java/lang/System.+ baseS + "super.baseS = " + super.baseS);
baseS = "ExplicitStatic";
java/lang/System.}
public static void main(
java/lang/String.ExplicitStatic x = new ExplicitStatic();
}
}
結果:
Base()
Cleanser(ExplicitStatic): s = Cleanser
ExplicitStatic():s2 = Cleanser, baseS = Cleanser, super.baseS = Cleanser
baseS = ExplicitStatic , super.baseS = Cleanser
二.關鍵字final
1.Final data
1.1 final data
1)當基本型別被定義為final,表示它的數(shù)據(jù)值不能被改變。如
final int i = 9;
i++;//編譯錯誤,不能改變I的值
2) 當object reference被定義為final時,不能改變的只是reference而不是對象本身。如
class Value{
int i = 1;
}
public class ExplicitStatic extends Cleanser{
public static void main(
java/lang/String.final Value v = new Value();//v.i = 1
v.i++;//v.i = 2
//v = new Value();
}
}
由于v為final,所以不能通過new Value()使v重新指向一個對象;但是v所指向的對象的值是可以改變的(v.i++)。
1.2 blank finals
我們可以將數(shù)據(jù)成員聲明為final但不給予初值,這就是blank finals。但blank finals必須且只能在構造函數(shù)中進行初始化。
public class ExplicitStatic {
final int ib;
final int i = 1;
ExplicitStatic()
{
ib = 2;//(a)
//i = 3; (b)
java/lang/System.}
public static void main(
java/lang/String.ExplicitStatic ex = new ExplicitStatic();
}
}
ib為blank finals,所以可以在構造函數(shù)中進行初始化。如果把(a)處的代碼注釋掉,則ib沒有初值,編譯出錯。而i在定義處已進行了初始化,則不能改變i的值,(b)處的代碼編譯錯誤。
**:非blank finals成員即使在構造函數(shù)中也不能更改其值
2.Final methods
1)被聲明為final的函數(shù)不能被覆寫
2)class中所有private函數(shù)自然而然會是final。
3.    Final classes
1)當一個class被聲明為final時,表示它不能被繼承,但class的數(shù)據(jù)成員不是final,可以被改變。如
class SmallBrain{}
final class Dinosaur{
int i = 7;
int j = i;
SmallBrain x = new SmallBrain();
void f(){};
}
//不能繼承final函數(shù)
//class Further extends Dinosaur{}
public class ExplicitStatic{
public static void main(
java/lang/String.Dinosaur n = new Dinosaur();
n.f();
n.i = 40;//final class中的non-final數(shù)據(jù)成員可以被改變
n.j++;
}
}
2)final class中的所有函數(shù)也都自然是final,因為沒有人能夠加以覆寫。
第7章    多態(tài)
一.再探向上轉型(upcasting)
將某個object reference視為一個“reference to base type“的動作,稱為向上轉型。
1.    Upcasting后調用某個函數(shù)時,如果derived class中覆寫了該函數(shù),則會調用derived class中的函數(shù);否則,會調用base class中的函數(shù)。如
class First{
public void prt(){
java/lang/System.}
}
class Second extends First{
//(a)
public void prt(){
java/lang/System.}
}
public class ExplicitStatic{
public static void main(
java/lang/String.First n = new Second();
n.prt();;
}
}
結果為Second。如果當Second class中的prt()函數(shù)注釋掉,將輸出First。
2.    向上轉型后只能調用base class中被derived class覆寫的函數(shù)。
/*
abstract class First{
int i = 122;
public void prt(){
System.out.println("First.i = " + i);
}
public abstract void prt(First f);
}
class Second extends First{
public void prt(){
System.out.println("Second.i = " + i);
}
public void prt(First i)
{
}
public void prt(int i)
{
}
}
public class ExplicitStatic{
public static void main(String[] args){
First n = new Second();
n.prt(2);;
}
}
*/
class First{
public void prt(){
java/lang/System.}
}
class Second extends First{
//(a)
public void prt(){
java/lang/System.}
public void prt(int i){//(a)
java/lang/System.}
}
public class ExplicitStatic{
public static void main(
java/lang/String.First n = new Second();
n.prt(3);
}
}
(a)處的函數(shù)只是Second class中的函數(shù),所以不能通過n.prt(3)進行調用。
二.Abstract class和Abstract methods
1.    如果一個class中存在abstract class,則class也必須被聲明為abstract class。
2.    abstract class不能被實例化。
3.    如果base class是一個abstract class,那么derived class必須實現(xiàn)base class中所有的abstract methods;否則,derived class也必須被聲明為abstract class。
三.其它要點
1.    純粹繼承與擴充
純粹繼承:只有base class所建議的函數(shù),才被derived class加以覆寫。
擴充:除了覆寫base class的函數(shù),還實現(xiàn)了自己的函數(shù)
abstract class First{
public abstract void f();
public abstract void g();
}
//純粹繼承
class Second extends First{
public void f(){}
public void g(){}
}
//擴充
class Third extends First{
public void f(){}
public void g(){}
public void u(){}//base class不存在的函數(shù)
}
2.    向下轉型
1)    向下轉型時只能調用base class中被覆寫過的函數(shù)
2)    只有本來就為derived class對象時才能正確向下轉弄。
class First{
public void f(){}
public void g(){}
}
class Second extends First{
public void f(){}
public void g(){}
public void u(){}
public void v(){}
}
public class ExplicitStatic{
public static void main(
java/lang/String.First[] x = {new First(), new Second()};
x[0].f();
x[1].g();
//!x[1].u();class First中不存在函數(shù)u()
//((Second)x[0]).f();(a)
((Second)x[1]).u();
}
}
-------------------------------------
本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
1.如何反射以及作用
Java 反射 使用總結
java核心技術之reflect(一):一個系統(tǒng)學習reflect的Demo(精)
java中的反射總結
Java 反射
Java學習之神奇的初始化
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服