2018.10.12學習筆記
阿新 • • 發佈:2018-11-10
10.12學習筆記
今天學習了《Java程式設計思想》的第十章—內部類的後半部分。下面對今日收穫與疑惑作一個總結。
1.匿名內部類:
將返回值的生成與表示這個返回值的類的定義結合在一起。另外,這個類是匿名的,他沒有名字。
①由於匿名內部類沒有名字,所以使用構造程式碼塊來代替建構函式
public abstract class Base { public Base(int i){ System.out.println("Base constructor, i = " + i); } public abstract void test(); } public class AnonymousBase { public Base getBase(int i){ return new Base(5){ {System.out.println("AnonymousBase initializer");}//構造程式碼塊充當了建構函式的功能 @Override public void test() { System.out.println("fuQian"); } }; } public static void main(String args[]){ AnonymousBase anonymousBase = new AnonymousBase(); anonymousBase.getBase(5).test(); } }
但是它收到了限制,不能過載例項初始化方法。
2.構造程式碼塊:
構造程式碼塊在類中用{}定義,作用是給物件進行初始化。構造程式碼塊與建構函式的區別是:構造程式碼塊是給所有的物件進行統一初始化,而建構函式是給對應的物件進行初始化。
①靜態程式碼塊與非靜態程式碼塊:
非靜態程式碼塊無論建立哪個物件,都會先執行相同的程式碼塊—構造程式碼塊中定義的是不同物件共性的初始化內容。靜態程式碼塊,它是隨著類的載入而執行,只執行一次。但無論是靜態程式碼塊還是非靜態程式碼塊,都會在構造方法呼叫之前被載入。
②初始化順序:
先載入靜態的,即靜態構造塊(類靜態屬性),然後才是非靜態的構造塊(非靜態屬性),最後才是呼叫類構造方法。注意靜態的,即靜態構造塊和靜態屬性不分先後,按在類定義的先後順序進行初始化
3.巢狀類(靜態內部類):
介面中的內部類:
巢狀類可以作為介面的一部分,因為類是static的,所以不違反介面的規則。放在介面中的任何類都自動地是public和static的,你甚至可以在內部類中實現其外圍介面。
public interface ClassInInterface { void howdy(); class Test implements ClassInInterface{ @Override public void howdy(){ System.out.println("介面的巢狀類"); } static class Tester{ public static void main(String args[]){ Test test = new Test(); test.howdy(); } } } }
4.為什麼需要內部類:
每個內部類都能獨立地實現一個介面或者繼承具體、抽象的類(相當於實現了多重繼承),或者可以讓多個類以不同的方式實現同一個介面或繼承自同一個類。
public interface Selector {
boolean end();
Object current();
void next();
}
/*
description:在同一個類中,建立兩個內部類實現了Selector介面的不同實現,從而實現了向前和向後進行遍歷
*/
public class Sequence {
private Object[] items;
private int next = 0;
public Sequence(int size){
items = new Object[size];
}
public void add(Object x){
if (next < items.length){
items[next++] = x;
}
}
private class SequenceSelector implements Selector{
private int i;
@Override
public boolean end(){
return i == items.length;
}
@Override
public Object current(){
return items[i];
}
@Override
public void next(){
if (i<items.length)
i++;
}
}
private class SequenceSelector_reverse implements Selector{
private int i = items.length -1;
@Override
public boolean end(){
return i == -1;
}
@Override
public Object current(){
return items[i];
}
@Override
public void next(){
if (i>=0)
i--;
}
}
public Selector selector(){
return new SequenceSelector();
}
public Selector selector_reverse(){
return new SequenceSelector_reverse();
}
public static class Tester{
public static void main(String args[]){
Sequence sequence = new Sequence(10);
Sequence sequence_reverse = new Sequence(10);
for (int i = 0;i< sequence.items.length;i++){
sequence.add(i);
sequence_reverse.add(i);
}
Selector selector = sequence.new SequenceSelector();
Selector selector_reverse = sequence.new SequenceSelector_reverse();
while (!selector.end()){
System.out.print(selector.current() + " ");
selector.next();
}
while(!selector_reverse.end()){
System.out.print(selector_reverse.current() + " ");
selector_reverse.next();
}
}
}
}/*output
0 1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1 0
*/
5.內部類的繼承:
因為內部類的構造器必須連線到指向其外部類物件的引用,所以,那個指向外部類物件的引用必須被初始化。
public class FirstOuter {
class FirstInner{
public FirstInner(int i){
System.out.println("第一個內部類" + i);
}
}
}
public class SecondOuter {
class SecondInner extends FirstOuter.FirstInner{
SecondInner(FirstOuter firstOuter,int i){ //外部類物件的引用以及傳入的引數
firstOuter.super(i);
}
}
}