隨著繼承層次中一個個新子類的定義,類變得越來越具體,而父類則更一般,更通用。類的設計應該保證父類和子類能夠共享特徵。有時將一個父類設計得非常抽象,以至於它沒有具體的實例,這樣的類叫做抽象類。
以下代碼中的Person類是一個抽象類
① 非匿名的類非匿名的對象
Worker worker = new Worker(); method1(worker);//非匿名的類非匿名的對象複製代碼
② 非匿名的類匿名的對象
method1(new Worker());複製代碼
③ 匿名子類的對象
Person p = new Person(){//Person是一個抽象類,不能實例化,這兒運用了多態的性質 @Override public void eat() { System.out.println(&34;); } }; method1(p);複製代碼
④ 匿名子類的匿名對象
method1(new Person(){ @Override public void eat() { System.out.println(&34;); } });複製代碼
Person p = new Student(&34;);複製代碼
GeometricObject[] objects = new CeometricObject[10];複製代碼
然後可以創建一個 CeometricObject 的實例,並將它的引用陚值給數組,如下所示: 複製代碼
objects[0] =new Circle();複製代碼
關於構造器與靜態方法的代碼如下:
abstract class AbstractClass{ /** * 輸出 */ abstract void print(); /** * */ public AbstractClass() {//抽象類中可以定義構造器,雖然不能初始化,可以被子類繼承 System.out.println(&34;); } public static void staticAbstractMethod() { System.out.println(&34;); }}/** * @author sir */public class AbstractClassTest extends AbstractClass{ public AbstractClassTest() { System.out.println(&34;); } @Override void print() { System.out.println(&34;); } public static void main(String[] args) { AbstractClassTest.staticAbstractMethod();//抽象類中可以定義靜態方法,可直接由類名調用 AbstractClass.staticAbstractMethod(); new AbstractClassTest().print(); }}複製代碼
輸出結果:
接口是一種與類相似的結構,它在許多方面都與抽象類很相似,但是它的目的是指明相關或者不相關類的多個對象的共同行為。接口就是規範,定義的是一組規則,體現了現實世界中「如果你是/要...則必須能...」的思想。繼承是一個&34;的關係,而接口實現則是 &34;的關係。 語法:
修飾符 interface 接口名 { /** 常量聲明 */ /** 方法籤名 */}複製代碼
定義Java類的語法格式:先寫extends,後寫implements
class SubClass extends SuperClass implements InterfaceA{ }複製代碼
接口示例:
public class USBTest { public static void main(String[] args) { Computer computer = new Computer(); //1.創建了接口的非匿名實現類的非匿名對象 Flash flash = new Flash(); computer.transferData(flash); //2. 創建了接口的非匿名實現類的匿名對象 computer.transferData(new Printer()); //3. 創建了接口的匿名實現類的非匿名對象 USB phone = new USB(){ @Override public void start() { System.out.println(&34;); } @Override public void stop() { System.out.println(&34;); } }; computer.transferData(phone); //4. 創建了接口的匿名實現類的匿名對象 computer.transferData(new USB(){ @Override public void start() { System.out.println(&34;); } @Override public void stop() { System.out.println(&34;); } }); }}class Computer{ public void transferData(USB usb){//USB usb = new Flash(); usb.start(); System.out.println(&34;); usb.stop(); }}interface USB{ //常量:定義了長、寬、最大最小的傳輸速度等 void start(); void stop();}class Flash implements USB{ @Override public void start() { System.out.println(&34;); } @Override public void stop() { System.out.println(&34;); }}class Printer implements USB{ @Override public void start() { System.out.println(&34;); } @Override public void stop() { System.out.println(&34;); }}複製代碼
除了定義全局常量和抽象方法之外,還可以定義靜態方法、默認方法 Java 8中,你可以為接口添加靜態方法和默認方法。從技術角度來說,這是完全合法的,只是它看起來違反了接口作為一個抽象定義的理念。
public interface CompareA { //靜態方法 public static void method1(){ System.out.println(&34;); } //默認方法 public default void method2(){ System.out.println(&34;); } default void method3(){ System.out.println(&34;); }}***********************************************public interface CompareB { default void method3(){ System.out.println(&34;); } }public class SuperClass { public void method3(){ System.out.println(&34;); } }**********************************************public class SubClassTest { public static void main(String[] args) { SubClass s = new SubClass(); // s.method1();// SubClass.method1(); //知識點1:接口中定義的靜態方法,只能通過接口來調用。 CompareA.method1(); //知識點2:通過實現類的對象,可以調用接口中的默認方法。 //如果實現類重寫了接口中的默認方法,調用時,仍然調用的是重寫以後的方法 s.method2(); //知識點3:如果子類(或實現類)繼承的父類和實現的接口中聲明了同名同參數的默認方法, //那么子類在沒有重寫此方法的情況下,默認調用的是父類中的同名同參數的方法。-->類優先原則 //知識點4:如果實現類實現了多個接口,而這多個接口中定義了同名同參數的默認方法, //那麼在實現類沒有重寫此方法的情況下,報錯。-->接口衝突。 //這就需要我們必須在實現類中重寫此方法 s.method3(); } }*************************************************************class SubClass extends SuperClass implements CompareA,CompareB{ public void method2(){ System.out.println(&34;); } public void method3(){ System.out.println(&34;); } //知識點5:如何在子類(或實現類)的方法中調用父類、接口中被重寫的方法 public void myMethod(){ method3();//調用自己定義的重寫的方法 super.method3();//調用的是父類中聲明的 //調用接口中的默認方法 CompareA.super.method3(); CompareB.super.method3(); }}複製代碼
輸出結果:
import java.util.Date;/** * @author mazouri * @create 2020-04-12 17:40 */public class CompareTest { public static void main(String[] args) { System.out.println((new Integer(3).compareTo(new Integer(5)))); // System.out.println((Integer.compare(3, 5)));當然可以用這個更好的方法 System.out.println(&34;.compareTo(&34;)); Date date1 = new Date(1990, 1, 1); Date date2 = new Date(1989, 6, 4); System.out.println(date1.compareTo(date2)); }}複製代碼
輸出結果:
題目: 定義一個接口用來實現兩個對象的比較。 interface CompareObject{ public int compareTo(Object o); //若返回值是 0 , 代表相等; 若為正數,代表當 前對象大;負數代表當前對象小 } 定義一個Circle類,聲明width,height屬性,提供getter和setter方法 定義一個ComparableRectangle.類,繼承Rectangle類並且實現CompareObject接口。在 ComparableCircle類中給出接口中方法compareTo的實現體,用來比較兩個長方形面積大小。 定義一個測試類ComparableRectangleTest,創建兩個ComparableRectangle對象,調用compareTo 方法比較兩個類的面積大小。
public interface CompareObject<C extends Rectangle> { /** * @return 若返回值是 0 , 代表相等; 若為正數,代表當前對象大;負數代表當前對象小 */ int compareTo(Object o);}******************************************************************public class Rectangle { private double width; private double height; public Rectangle() { } public Rectangle(double width, double height) { this.width = width; this.height = height; } public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } public double getArea() { return height * width; }}******************************************************************public class ComparableRectangle extends Rectangle implements CompareObject { public ComparableRectangle() { } public ComparableRectangle(double width, double height) { super(width, height); } @Override public int compareTo(Object o) { if (this == o) { return 0; } if (o instanceof ComparableRectangle) { ComparableRectangle c = (ComparableRectangle) o; // return Double.compare(getArea(), c.getArea()); if (getArea() > c.getArea()) { return 1; } else if (getArea() < c.getArea()) { return -1; } else { return 0; } } else { throw new RuntimeException(&34;); } }}******************************************************************public class ComparableRectangleTest { public static void main(String[] args) { ComparableRectangle c1 = new ComparableRectangle(2.2, 3.4); ComparableRectangle c2 = new ComparableRectangle(2.3, 3.4); int compareValue = c1.compareTo(c2); if (compareValue > 0) { System.out.println(&34;); } else if (compareValue < 0) { System.out.println(&34;); } else { System.out.println(&34;); } }}複製代碼
輸出結果:
分類: ① 成員內部類(static成員內部類和非static成員內部類) ② 局部內部類(不談修飾符)、匿名內部類
java局部內部類就是在方法中定義的類,它僅在該方法中有效。
class 外部類{方法(){ class 局部內部類{ } } { class 局部內部類{ } } }複製代碼
匿名內部類不能定義任何靜態成員、方法和類,只能創建匿名內部類的一個實例。一個匿名內部類一定是在new的後面,用其隱含實現一個接口或實現一個類。 格式:
new 父類構造器(實參列表)實現接口(){//匿名內部類的類體部分} 複製代碼
interface A{public abstract void fun1();}public class Outer{public static void main(String[] args) {new Outer().callInner(new A(){//接口是不能new但此處比較特殊是子類對象實現接口,只不過沒有為對象取名public void fun1() {System.out.println(「implement for fun1&34;黃鸝&34;小明&34;人:吃飯&34;卡拉是條狗&34;杜鵑&34;我是一隻小小鳥"); Person.this.eat();//調用外部類的非靜態屬性 eat(); System.out.println(age); } public void display(String name){ System.out.println(name);//方法的形參 System.out.println(this.name);//內部類的屬性 System.out.println(Person.this.name);//外部類的屬性 } }} 複製代碼
輸出結果:
作者:馬走日lx
連結:https://juejin.im/post/6864894289751572493