<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # Java 面向對象編程 II 原文:http://zetcode.com/lang/java/oop2/ 在 Java 教程的這一章中,我們將繼續對 Java OOP 的描述。 我們提到了抽象類和方法,接口,多態以及各種嵌套類。 ## Java 抽象類和方法 在設計應用時,我們經常發現我們的類具有很多通用功能。 這些共同點可以被提取并放入父類中。 這樣,我們可以減少代碼的大小,并使我們的應用更緊湊。 我們可能會發現父類是無形的,虛幻的實體-一個想法。 在桌子上,我們有一支筆,一本書,一支鉛筆或一杯茶。 一個項目可能被視為所有這些事情的父類。 該類將包含這些項目的一些常見特質。 例如 id,權重或顏色。 我們可以實現`getId()`方法,但是不能在此類中實現`getWeight()`或`getColor()`方法。 物品沒有重量或顏色。 這些方法只能在`Item`類的子類中實現。 對于這些情況,我們有抽象的方法和類。 `Item`類是抽象類的候選人-抽象類不能創建,并且其某些或所有方法不能實現。 使用`abstract`關鍵字創建抽象類或方法。 抽象類不能被實例化,但是可以被子類化。 如果一個類至少包含一個抽象方法,則也必須將其聲明為抽象方法。 抽象方法無法實現; 他們只是聲明方法的簽名。 當我們從抽象類繼承時,所有抽象方法都必須由派生類實現,或者該類本身必須是抽象的。 單個抽象類由相似類的子類繼承,這些相似類具有很多共同點(抽象類的實現部分),但也有一些區別(抽象方法)。 抽象類可能具有完全實現的方法,也可能具有定義的成員字段。 因此,抽象類可以提供部分實現。 程序員經常將一些通用功能放入抽象類中。 這些抽象類隨后會被子類化以提供更具體的實現。 通用功能在抽象類中實現,不同之處由抽象方法提示。 例如,Qt 圖形庫具有`QAbstractButton`,它是按鈕小部件的抽象基類,提供按鈕所共有的功能。 按鈕`Q3Button`,`QCheckBox`,`QPushButton`,`QRadioButton`和`QToolButton`從此基本抽象類繼承并提供其特定功能。 `static`,`private`和`final`方法不能是抽象的,因為這些類型的方法不能被子類覆蓋。 同樣,`final`類不能具有任何抽象方法。 正式地說,抽象類用于強制執行協議。 協議是所有實現對象都必須支持的一組操作。 `AbstractClass.java` ```java package com.zetcode; abstract class Drawing { protected int x = 0; protected int y = 0; public abstract double area(); public String getCoordinates() { return String.format("x: %d, y: %d", this.x, this.y); } } class Circle extends Drawing { private int r; public Circle(int x, int y, int r) { this.x = x; this.y = y; this.r = r; } @Override public double area() { return this.r * this.r * Math.PI; } @Override public String toString() { return String.format("Circle at x: %d, y: %d, radius: %d", this.x, this.y, this.r); } } public class AbstractClass { public static void main(String[] args) { Circle c = new Circle(12, 45, 22); System.out.println(c); System.out.format("Area of circle: %f%n", c.area()); System.out.println(c.getCoordinates()); } } ``` 我們有一個抽象基類`Drawing`。 該類定義兩個成員字段,定義一個方法并聲明一個方法。 一種方法是抽象的,另一種是完全實現的。 `Drawing`類是抽象的,因為我們無法繪制它。 我們可以畫一個圓,一個點或一個正方形,但是我們不能畫一個`Drawing`。 `Drawing`類對我們可以繪制的對象具有一些通用功能。 ```java abstract class Drawing { ``` 我們使用`abstract`關鍵字定義一個抽象類。 ```java public abstract double area(); ``` 抽象方法之前還帶有`abstract`關鍵字。 `Drawing`類是一個想法。 這是不真實的,我們無法為其實現`area()`方法。 在這種情況下,我們使用抽象方法。 該方法將在更具體的實體(例如圓圈)中實現。 ```java class Circle extends Drawing { ``` `Circle`是`Drawing`類的子類。 因此,它必須實現抽象的`area()`方法。 ```java @Override public double area() { return this.r * this.r * Math.PI; } ``` 在這里,我們正在實現`area()`方法。 ```java $ java com.zetcode.AbstractClass Circle at x: 12, y: 45, radius: 22 Area of circle: 1520.530844 x: 12, y: 45 ``` 我們創建一個`Circle`對象并打印其面積和坐標。 ## Java 接口 遙控器是觀眾和電視之間的接口。 它是此電子設備的接口。 外交禮儀指導外交領域的所有活動。 道路規則是駕車者,騎自行車的人和行人必須遵守的規則。 編程中的接口類似于前面的示例。 接口是: * API * 合約 對象通過其公開的方法與外界交互。 實際的實現對程序員而言并不重要,或者也可能是秘密的。 公司可能會出售圖書館,但它不想透露實際的實現情況。 程序員可能會在 GUI 工具箱的窗口上調用`maximize()`方法,但對如何實現此方法一無所知。 從這個角度來看,接口是對象與外界交互的方式,而又不會過多地暴露其內部功能。 從第二個角度來看,接口就是契約。 如果達成協議,則必須遵循。 它們用于設計應用的架構。 他們幫助組織代碼。 接口是完全抽象的類型。 它們使用`interface`關鍵字聲明。 在 Java 中,接口是引用類型,類似于只能包含常量,方法簽名和嵌套類型的類。 沒有方法主體。 接口無法實例化-它們只能由類實現或由其他接口擴展。 所有接口成員都隱式具有公共訪問權限。 接口不能具有完全實現的方法。 Java 類可以實現任何數量的接口。 接口掃描還可以擴展任何數量的接口。 實現接口的類必須實現接口的所有方法簽名。 接口用于模擬多重繼承。 Java 類只能從一個類繼承,但可以實現多個接口。 具有接口的多重繼承與繼承方法和變量無關,而與繼承接口所描述的思想或契約有關。 接口的主體包含抽象方法,但是根據定義,由于接口中的所有方法都是抽象的,因此不需要`abstract`關鍵字。 由于接口指定了一組公開的行為,因此所有方法都是隱式公共的。 接口除了方法聲明外,還可以包含常量成員聲明。 接口中定義的所有常數值都是`public`,`static`和`final`隱式。 這些修飾符可以省略。 接口和抽象類之間有一個重要的區別。 抽象類為繼承層次結構中相關的類提供部分實現。 另一方面,可以通過彼此不相關的類來實現接口。 例如,我們有兩個按鈕。 經典按鈕和圓形按鈕。 兩者都繼承自抽象按鈕類,該類為所有按鈕提供了一些通用功能。 實現類是相關的,因為它們都是按鈕。 而類別`Database`和`SignIn`彼此不相關。 我們可以應用`ILoggable`接口,該接口將迫使他們創建執行日志記錄的方法。 `SimpleInterface.java` ```java package com.zetcode; interface IInfo { void doInform(); } class Some implements IInfo { @Override public void doInform() { System.out.println("This is Some Class"); } } public class SimpleInterface { public static void main(String[] args) { Some sm = new Some(); sm.doInform(); } } ``` 這是一個演示接口的簡單 Java 程序。 ```java interface IInfo { void doInform(); } ``` 這是接口`IInfo`。 它具有`doInform()`方法簽名。 ```java class Some implements IInfo { ``` 我們實現了`IInfo`接口。 要實現特定的接口,我們使用`implements`關鍵字。 ```java @Override public void doInform() { System.out.println("This is Some Class"); } ``` 該類提供了`doInform()`方法的實現。 `@Override`注解告訴編譯器我們正在重寫方法。 Java 不允許直接從多個類中繼承。 它允許實現多個接口。 下一個示例顯示了一個類如何實現多個接口。 `MultipleInterfaces.java` ```java package com.zetcode; interface Device { void switchOn(); void switchOff(); } interface Volume { void volumeUp(); void volumeDown(); } interface Pluggable { void plugIn(); void plugOff(); } class CellPhone implements Device, Volume, Pluggable { @Override public void switchOn() { System.out.println("Switching on"); } @Override public void switchOff() { System.out.println("Switching on"); } @Override public void volumeUp() { System.out.println("Volume up"); } @Override public void volumeDown() { System.out.println("Volume down"); } @Override public void plugIn() { System.out.println("Plugging in"); } @Override public void plugOff() { System.out.println("Plugging off"); } } public class MultipleInterfaces { public static void main(String[] args) { CellPhone cp = new CellPhone(); cp.switchOn(); cp.volumeUp(); cp.plugIn(); } } ``` 我們有一個`CellPhone`類,它從三個接口繼承。 ```java class CellPhone implements Device, Volume, Pluggable { ``` 該類實現所有三個用逗號分隔的接口。 `CellPhone`類必須實現來自所有三個接口的所有方法簽名。 ```java $ java com.zetcode.MultipleInterfaces Switching on Volume up Plugging in ``` 運行程序,我們得到此輸出。 下一個示例顯示接口如何形成層次結構。 接口可以使用`extends`關鍵字從其他接口繼承。 `InterfaceHierarchy.java` ```java package com.zetcode; interface IInfo { void doInform(); } interface IVersion { void getVersion(); } interface ILog extends IInfo, IVersion { void doLog(); } class DBConnect implements ILog { @Override public void doInform() { System.out.println("This is DBConnect class"); } @Override public void getVersion() { System.out.println("Version 1.02"); } @Override public void doLog() { System.out.println("Logging"); } public void connect() { System.out.println("Connecting to the database"); } } public class InterfaceHierarchy { public static void main(String[] args) { DBConnect db = new DBConnect(); db.doInform(); db.getVersion(); db.doLog(); db.connect(); } } ``` 我們定義了三個接口。 接口按層次結構組織。 ```java interface ILog extends IInfo, IVersion { ``` `ILog`接口從兩個接口繼承。 ```java class DBConnect implements ILog { ``` `DBConnect`類實現`ILog`接口。 因此,它必須實現所有三個接口的方法。 ```java @Override public void doInform() { System.out.println("This is DBConnect class"); } ``` `DBConnect`類實現`doInform()`方法。 該方法由該類實現的`ILog`接口繼承。 ```java $ java com.zetcode.InterfaceHierarchy This is DBConnect class Version 1.02 Logging Connecting to the database ``` 這是示例輸出。 ## Java 多態 多態是對不同的數據輸入以不同方式使用運算符或函數的過程。 實際上,多態意味著如果類 B 從類 A 繼承,則不必繼承關于類 A 的所有內容; 它可以完成 A 類所做的某些事情。 通常,多態是以不同形式出現的能力。 從技術上講,它是重新定義派生類的方法的能力。 多態與將特定實現應用于接口或更通用的基類有關。 簡而言之,多態是重新定義派生類的方法的能力。 `Polymorphism.java` ```java package com.zetcode; abstract class Shape { protected int x; protected int y; public abstract int area(); } class Rectangle extends Shape { public Rectangle(int x, int y) { this.x = x; this.y = y; } @Override public int area() { return this.x * this.y; } } class Square extends Shape { public Square(int x) { this.x = x; } @Override public int area() { return this.x * this.x; } } public class Polymorphism { public static void main(String[] args) { Shape[] shapes = { new Square(5), new Rectangle(9, 4), new Square(12) }; for (Shape shape : shapes) { System.out.println(shape.area()); } } } ``` 在上面的程序中,我們有一個抽象的`Shape`類。 此類演變為兩個后代類別:`Rectangle`和`Square`。 兩者都提供了自己的`area()`方法實現。 多態為 OOP 系統帶來了靈活性和可伸縮性。 ```java @Override public int area() { return this.x * this.y; } ... @Override public int area() { return this.x * this.x; } ``` `Rectangle`和`Square`類具有`area()`方法的自己的實現。 ```java Shape[] shapes = { new Square(5), new Rectangle(9, 4), new Square(12) }; ``` 我們創建三個形狀的數組。 ```java for (Shape shape : shapes) { System.out.println(shape.area()); } ``` 我們遍歷每個形狀,并在其上調用`area()`方法。 編譯器為每種形狀調用正確的方法。 這就是多態的本質。 ## Java 嵌套類 可以在另一個類中定義一個類。 這種類在 Java 術語中稱為嵌套類。 非嵌套類的類稱為頂級類。 Java 有四種類型的嵌套類: * 靜態嵌套類 * 內部類 * 本地類 * 匿名類 使用嵌套類可以提高代碼的可讀性并改善代碼的組織。 內部類通常在 GUI 中用作回調。 例如在 Java Swing 工具箱中。 ## Java 靜態嵌套類 靜態嵌套類是可以在沒有封閉類實例的情況下創建的嵌套類。 它可以訪問封閉類的靜態變量和方法。 `SNCTest.java` ```java package com.zetcode; public class SNCTest { private static int x = 5; static class Nested { @Override public String toString() { return "This is a static nested class; x:" + x; } } public static void main(String[] args) { SNCTest.Nested sn = new SNCTest.Nested(); System.out.println(sn); } } ``` 該示例展示了一個靜態的嵌套類。 ```java private static int x = 5; ``` 這是`SNCTest`類的私有靜態變量。 可以通過靜態嵌套類訪問它。 ```java static class Nested { @Override public String toString() { return "This is a static nested class; x:" + x; } } ``` 定義了一個靜態的嵌套類。 它具有一種打印消息并引用靜態`x`變量的方法。 ```java SNCTest.Nested sn = new SNCTest.Nested(); ``` 點運算符用于引用嵌套類。 ```java $ java com.zetcode.SNCTest This is a static nested class; x:5 ``` 這是`com.zetcode.SNCTest`程序的輸出。 ## Java 內部類 普通或頂級類的實例可以單獨存在。 相比之下,內部類的實例必須綁定到頂級類才能實例化。 內部類也稱為成員類。 它們屬于封閉類的實例。 內部類可以訪問封閉類的成員。 `InnerClassTest.java` ```java package com.zetcode; public class InnerClassTest { private int x = 5; class Inner { @Override public String toString() { return "This is Inner class; x:" + x; } } public static void main(String[] args) { InnerClassTest nc = new InnerClassTest(); InnerClassTest.Inner inner = nc.new Inner(); System.out.println(inner); } } ``` 在`InnerClassTest`類中定義了一個嵌套類。 它可以訪問成員`x`變量。 ```java class Inner { @Override public String toString() { return "This is Inner class; x:" + x; } } ``` `InnerClassTest`類的主體中定義了`Inner`類。 ```java InnerClassTest nc = new InnerClassTest(); ``` 首先,我們需要創建頂級類的實例。 沒有封閉類的實例,內部類將不存在。 ```java InnerClassTest.Inner inner = nc.new Inner(); ``` 一旦實例化了頂級類,就可以創建內部類的實例。 ```java $ java com.zetcode.InnerClassTest This is Inner class; x:5 ``` 這是`com.zetcode.InnerClassTest`程序的輸出。 ## Java 變量隱藏 如果內部作用域中的變量與外部作用域中的變量具有相同的名稱,則將其隱藏。 仍然可以在外部范圍中引用該變量。 `Shadowing.java` ```java package com.zetcode; public class Shadowing { private int x = 0; class Inner { private int x = 5; void method1(int x) { System.out.println(x); System.out.println(this.x); System.out.println(Shadowing.this.x); } } public static void main(String[] args) { Shadowing sh = new Shadowing(); Shadowing.Inner si = sh.new Inner(); si.method1(10); } } ``` 我們在頂級類,內部類和方法內部定義一個`x`變量。 ```java System.out.println(x); ``` 該行引用在方法的本地范圍內定義的`x`變量。 ```java System.out.println(this.x); ``` 使用`this`關鍵字,我們引用`Inner`類中定義的`x`變量。 ```java System.out.println(Shadowing.this.x); ``` 在這里,我們指的是`Shadowing`頂級類的`x`變量。 ```java $ java com.zetcode.Shadowing 10 5 0 ``` 這是示例輸出。 ## Java 本地類 本地類是內部類的特例。 本地類是在塊中定義的類。 (塊是括號之間的零個或多個語句的組。)本地類可以訪問其封閉類的成員。 此外,如果聲明了`final`,則本地類可以訪問本地變量。 原因是技術上的。 本地類實例的生存期可能比定義該類的方法的執行時間更長。 為了解決這個問題,將局部變量復制到局部類中。 為了確保以后不會更改它們,必須將它們聲明為`final`。 本地類別不能為`public`,`private`,`protected`或`static`。 不允許將它們用于局部變量聲明或局部類聲明。 除了聲明為`static`和`final`的常量外,局部類不能包含靜態字段,方法或類。 `LocalClassTest.java` ```java package com.zetcode; public class LocalClassTest { public static void main(String[] args) { final int x = 5; class Local { @Override public String toString() { return "This is Local class; x:" + x; } } Local loc = new Local(); System.out.println(loc); } } ``` 本地類在`main()`方法的主體中定義。 ```java @Override public String toString() { return "This is Local class; x:" + x; } ``` 如果局部類聲明為`final`,則可以訪問它們。 ## Java 匿名類 匿名類是沒有名稱的本地類。 它們使我們能夠同時聲明和實例化一個類。 如果我們只想使用匿名類,則可以使用匿名類。 匿名類在單個表達式中定義和實例化。 當事件處理代碼僅由一個組件使用,因此不需要命名引用時,也可以使用匿名內部類。 匿名類必須實現接口或從類繼承。 但是不使用`implements`和`extends`關鍵字。 如果`new`關鍵字后面的名稱是類的名稱,則匿名類是命名類的子類。 如果在`new`之后的名稱指定了接口,則匿名類將實現該接口并擴展`Object`。 由于匿名類沒有名稱,因此無法為匿名類定義構造器。 在匿名類的主體內部,我們無法定義任何語句; 僅方法或成員。 `AnonymousClass.java` ```java package com.zetcode; public class AnonymousClass { interface Message { public void send(); } public void createMessage() { Message msg = new Message() { @Override public void send() { System.out.println("This is a message"); } }; msg.send(); } public static void main(String[] args) { AnonymousClass ac = new AnonymousClass(); ac.createMessage(); } } ``` 在此代碼示例中,我們創建一個匿名類。 ```java interface Message { public void send(); } ``` 匿名類必須是子類或必須實現接口。 我們的匿名類將實現`Message`接口。 否則,編譯器將無法識別類型。 ```java public void createMessage() { Message msg = new Message() { @Override public void send() { System.out.println("This is a message"); } }; msg.send(); } ``` 匿名類是本地類,因此它是在方法主體中定義的。 表達式中定義了一個匿名類。 因此,右括號后面是一個分號。 在 Java 教程的這一部分中,我們繼續介紹 Java 中的面向對象編程。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看