日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

CoreJava 笔记总结-第五章 继承

發布時間:2023/12/4 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CoreJava 笔记总结-第五章 继承 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 第五章 繼承
    • 類、超類和子類
      • 定義子類
      • 覆蓋方法
      • 子類構造器
      • 多態
      • 阻止繼承: `final`類和方法
      • 強制類型轉換
      • 抽象類
      • 受保護訪問
    • 訪問控制修飾符小結
    • `Object`: 所有類的超類
      • `Object`類型的變量
      • `equals`方法
      • 相等測試與繼承
      • `hashCode`方法
      • `toString`方法
    • ==泛型數組列表==
      • 聲明數組列表
      • 訪問數組列表元素
      • 類型化與原始數組列表的兼容性
    • 對象包裝器與自動裝箱
    • 參數數量可變的方法
    • 枚舉類
    • 反射
      • `Class`類
      • 聲明異常入門
      • 利用反射分析類的能力
    • 繼承的設計技巧

第五章 繼承

類、超類和子類

定義子類

  • extend: 該關鍵字表示繼承
public class Manager extends Employee // java中所有的繼承都是公共繼承 {added methods and fields }
  • extend: 表示正在構造的類派生于一個已存在的類.這個已存在的類稱為超類(基類,父類). 新類稱為子類(派生類, 孩子類)
  • 子類比超類擁有更多的功能
  • 設計類: 最一般的類放在超類中, 更特殊的方法放入子類

覆蓋方法

  • super: 調用超類方法

    public class Manager extends Employee {public double getSalary(){double baseSalary = super.getSalary();return baseSalary + bonus;} }

子類構造器

  • 由于Manager構造器不能訪問Emplyee類的私有字段, 所以通過super來調用初始化這些私有字段

    public Manager(String name, double salary, int year, int month, int day) {super(name, salary, year, month, day);//必須放在第一句bonus = 0; }
  • this: 1. 隱式參數的引用 2. 調用該類的其他構造器

    super: 1. 調用其他超類的方法 2. 調用超類的構造器


多態

  • 多態: 一個變量能夠指示多種實際類型的現象
Manager boss = new Manager(...) Employee[] staff = new Employee[3]; staff[0] = boss;
  • 上面的例子中boss, staff[0]指示同一個對象, 但是編譯器只將staff[0]看成一個Emplyee對象
  • 子類引用的數組可以轉換成超類引用的數組
Manager[] managers = new Manager[10]; Employee[] staff = managers;
  • 重載解析: 選擇所有名字相同的方法中存在一個與提供參數完全相匹配的方法
  • 簽名: 方法的名字和參數列表. 返回類型不是簽名的一部分
  • 在覆蓋一個方法時,子類方法不能低于超類方法的可見性.e.g.: 超類為public, 子類也必須為public

阻止繼承: final類和方法

  • final類: 不允許擴展的類, 其中的方法自動設置成為fianl方法, 不包括字段
  • final方法: 子類不能覆蓋的方法
  • fianl字段: 構造對象后就不允許改變其值

強制類型轉換

  • Manager boss = (Manager) staff[0];

  • Manager boss = (Manager) staff[1]; // ERROR 拋出異常: ClassCastException

  • if (staff[1] instanceof Manager){boss = (Manager) staff[1];.... }//查看能否強制類型轉換成功
  • 繼承層次: 由一個公共類派生出來所有類的集合

  • 只能在繼承層次類進行強制類型轉換
  • 在將超類強制類型轉換為子類之前, 應該用instanceof進行檢查

抽象類

  • 位于上層的類更具有一般性,更加抽象

  • 包含一個及以上抽象方法的類必須聲明為抽象類

  • public abstract class Person {...public abstract String getDescription(); }
  • 抽象類也可以包含字段和具體方法

  • 抽象類不能實例化. new Person("dvsj"); //ERROR

  • 可以定義一個抽象類的對象變量, 引用非抽象子類的對象

Person p = new Student("Alice"); package chapter5_inheritance.abstruct_classes;public abstract class Person {//抽象類public abstract String getDescription();//抽象方法private String name;public Person(String name) {this.name = name;}public String getName() {//抽象類中也可以由方法return name;} }package chapter5_inheritance.abstruct_classes;public class Student extends Person {private String major;/*** @param name the student's name* @param major the student's major*/public Student(String name, String major) {super(name); // 繼承Personthis.major = major;//隱式參數的引用}public String getDescription() { // 對應抽象類中的抽象方法return "A student major in " + major;} }package chapter5_inheritance.abstruct_classes;import java.time.LocalDate;public class Employee extends Person {private double salary;private LocalDate hireDay;public Employee(String name, double salary, int year, int month, int day) {super(name);this.salary = salary;hireDay = LocalDate.of(year, month, day);}public double getSalary() {return salary;}public LocalDate getHireDay() {return hireDay;}public void raiseSalary(double byPercent) {double delta = salary * byPercent / 100;salary += delta;}public String getDescription() {return String.format("An employee with a salary of %.2f", salary);} }package chapter5_inheritance.abstruct_classes;public class Person_test {public static void main(String[] args) {/* 聲明為Person類型 */var people = new Person[2];/* 每一個Person類型的people[i] 聲明為對應子類類型 */people[0] = new Student("oukunnan", "Software Engineering");people[1] = new Employee("vfjh", 1500.0, 1259, 5, 12);/* 注意點 類型 參數: 實參數組 */for (Person p : people) {System.out.println(p.getName() + ", " + p.getDescription());}} }

受保護訪問

  • protected: 限制超類中某個方法只允許子類訪問, 希望允許子類的方法訪問超類的某個字段
  • 保護字段只能由同一個包中的類訪問

訪問控制修飾符小結

  • private: 僅對本類可見
  • public: 對外部完全可見
  • protected: 對本包和所有子類可見
  • 無: 對本包可見, 不需要修飾符

  • Object: 所有類的超類

    Object類型的變量

    • 可以使用object類型的變量引用任何類型的對象
    Object obj = new Employee("sbjd", 2000);
    • 只能作為各種值的一個泛型容器, 進行具體操作需要強制類型轉換
    Employee e = (Employee)obj;
    • 只有基本類型不是對象: 數值, 字符, 布爾類型的值

    equals方法

    • 該方法確定兩個對象的引用是否相等
    public boolean equals(Object otherObject) {if (this == otherObject) {return true;}//判引用if (otherObject == null) {return false;}//判空if (getClass() != otherObject.getClass()) {return false;}//判對象所屬類是否相等Employee other = (Employee) otherObject;//調用Object.equals()而不是name.equals(other.name)為了防備name, hireDay為null情況return Objects.equals(name, other.name) && salary == other.salary&& Objects.equals(hireDay, other.hireDay); }
    • 子類中: if(!super.equals(otherObject)) return false; ...

    相等測試與繼承

    • equals方法要求: 自反性, 對稱性, 傳遞性, 一致性
    • 比較數組元素是否相等, 使用靜態方法Arrays.equals
    • @Override標記要覆蓋超類的那些子類方法

    hashCode方法

    • 散列碼: 值由對象的儲存地址得出
    • 字符串的散列碼時由內容導出的
    • Object.hasCode: null安全的方法
    • Object.hash():組合多個散列值, 這個方法對于各個參數調用Object.hasCode()
    • Arrays.hashCode:數組類型字段計算散列碼
    • hasCode, equals方法必須兼容

    toString方法

    • x.toString() 等價于 "" + x
    • System.out.println(x)會自動調用x.toString()
    • 對于數組: Arrays.toString, Arrays.deepToString

    泛型數組列表

    • ArrayList類: 類似于數組, 在添加或者刪除數組元素時可以自動調整數組容量
    • 它是一個有類型參數的泛型類

    聲明數組列表

    • 以下三種聲明方式等價
    ArrayList<Employee> staff = new ArrayList<Employee>(); ArrayList<Employee> staff = new ArrayList<>(); // 菱形語法 var staff = new ArrayList<Employee>();
    • add: 將元素添加到列表中
    • ensureCapacity: 確保數組列表在不重新分配內部儲存數組的情況下有足夠容量儲存給定數量的元素
    • trimToSize: 將數組列表的存儲容量消減到當前大小
    • size: staff.size() 等價于數組的a.length, 表示實際包含元素個數

    訪問數組列表元素

    • get: 得到指定索引位置的值
    • set: 重新設置索引位置已經存在的值
    • add(int index, E obj):后移元素從而插入obj到指定位置
    • remov(int index): 刪除指定索引位置的元素, 后面的元素前移
    • toArray: 將數組元素拷貝到一個數組中
    list.toArray(a); //將數組列表list中的元素拷貝到數組a中

    類型化與原始數組列表的兼容性

    • public class EmployeeDB {public void update(ArrayList list){...}public ArrayList find(String query) {...}
    • 可以將類型化的數組列表傳遞給update, 不需要強制類型轉換

    • 但是原始ArrayList賦給類型化ArrayList會有警告, 強制類型轉換也不可以消除警告,會引發類型轉換有誤的另一個警告

    • @SuppressWarning("unchecked") ArrayList<Employee> result = (ArrayList<Employee>) emplyeeDB.find(x);
    • 用以上注解標記問題不太嚴重的強制類型轉換的變量


    對象包裝器與自動裝箱

    • 包裝器: 所有的基本類型對應的類(Integer, Double, Long, Float, Short, Byte, Character, Boolean)

    • 包裝器類是final, 不能派生子類

    • 尖括號中的類型參數不允許是基本類型, 可以這樣var list = new ArrayList<Integer>();

    • 自動裝箱:

      list.add(3) --> list.add(Integer.valueOf(3))
    • 自動拆箱:

    int n = list.get(i); --> list.get(i).intValue();
    • Integer a = 1000; Integer b = 1000; if (a == b) ..//通常失敗

      ==運算符比較的是對象是否占有相同的內存位置

    • -128~127之間的short, int被包裝到固定的對象中, 上面的比較就會成功


    參數數量可變的方法

    • ...: 是Java代碼的一部分, 表示這個方法可以接受任意數量的對象

      public class PrintStream {public PrintStream printf(String fmt, Object... args){return format(fmt, args);} }
    • printf方法接受兩個參數, 一個是格式化字符串, 另一個是Object[]數組, 其中保存著所有其他參數(整數或者其他基本類型的值會自動裝箱為對象), Object...參數類型和Object[]完全一樣


    枚舉類

    • public enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARG};
    • 枚舉構造器總是私有的
    • 所有枚舉類型都是Enum的子類
    • values: 返回一個包含全部枚舉值的數組

    反射

    • 反射: 能夠分析類能力的程序

    Class類

    • getClass: 返回類的名字
    • forName: 獲得類名對應的Class對象
    • T.class: 代表匹配的類對象
    • Class實際上是泛型類, Employee.class-->Class<Employee>

    聲明異常入門

    • 處理器處理拋出的異常
    • 異常分為
    • 非檢查型異常
    • 檢查型異常

    利用反射分析類的能力

    • java.lang.reflect包中有三個類Field, Method, Constructor分別用于描述類的字段,方法和構造器, 這三個類都有一個gteName方法, 返回其名稱
    • Class類中的getFields, getMethods, getConstructors 方法返回這個類支持的公共字段,方法和構造器的數組, 其中包括超類的公共成員
    • Class類中的getDeclaredFields, getDeclareMethods, getDeclaredConstructors 方法返回這個類聲明的全部字段,方法和構造器,包括私有成員,包成員,受保護成員,不包括超類成員
    package chapter5_inheritance;import java.util.*; import java.lang.reflect.*;public class reflection {public static void main(String[] args)throws ReflectiveOperationException{// read class name from command line args or user inputString name;if (args.length > 0) name = args[0];else{var in = new Scanner(System.in);System.out.println("Enter class name (e.g. java.util.Date): ");name = in.next();}// print class name and superclass name (if != Object)Class cl = Class.forName(name);Class supercl = cl.getSuperclass();String modifiers = Modifier.toString(cl.getModifiers());if (modifiers.length() > 0) System.out.print(modifiers + " ");System.out.print("class " + name);if (supercl != null && supercl != Object.class) System.out.print(" extends "+ supercl.getName());System.out.print("\n{\n");printConstructors(cl);System.out.println();printMethods(cl);System.out.println();printFields(cl);System.out.println("}");}/*** Prints all constructors of a class* @param cl a class*/public static void printConstructors(Class cl){Constructor[] constructors = cl.getDeclaredConstructors();for (Constructor c : constructors){String name = c.getName();System.out.print(" ");String modifiers = Modifier.toString(c.getModifiers());if (modifiers.length() > 0) System.out.print(modifiers + " ");System.out.print(name + "(");// print parameter typesClass[] paramTypes = c.getParameterTypes();for (int j = 0; j < paramTypes.length; j++){if (j > 0) System.out.print(", ");System.out.print(paramTypes[j].getName());}System.out.println(");");}}/*** Prints all methods of a class* @param cl a class*/public static void printMethods(Class cl){Method[] methods = cl.getDeclaredMethods();for (Method m : methods){Class retType = m.getReturnType();String name = m.getName();System.out.print(" ");// print modifiers, return type and method nameString modifiers = Modifier.toString(m.getModifiers());if (modifiers.length() > 0) System.out.print(modifiers + " ");System.out.print(retType.getName() + " " + name + "(");// print parameter typesClass[] paramTypes = m.getParameterTypes();for (int j = 0; j < paramTypes.length; j++){if (j > 0) System.out.print(", ");System.out.print(paramTypes[j].getName());}System.out.println(");");}}/*** Prints all fields of a class* @param cl a class*/public static void printFields(Class cl){Field[] fields = cl.getDeclaredFields();for (Field f : fields){Class type = f.getType();String name = f.getName();System.out.print(" ");String modifiers = Modifier.toString(f.getModifiers());if (modifiers.length() > 0) System.out.print(modifiers + " ");System.out.println(type.getName() + " " + name + ";");}} }/* Enter class name (e.g. java.util.Date): java.lang.Double public final class java.lang.Double extends java.lang.Number {public java.lang.Double(double);public java.lang.Double(java.lang.String);public boolean equals(java.lang.Object);public static java.lang.String toString(double);public java.lang.String toString();public int hashCode();public static int hashCode(double);public static double min(double, double);public static double max(double, double);public static native long doubleToRawLongBits(double);public static long doubleToLongBits(double);public static native double longBitsToDouble(long);public volatile int compareTo(java.lang.Object);public int compareTo(java.lang.Double);public byte byteValue();public short shortValue();public int intValue();public long longValue();public float floatValue();public double doubleValue();public static java.lang.Double valueOf(java.lang.String);public static java.lang.Double valueOf(double);public static java.lang.String toHexString(double);public static int compare(double, double);public static boolean isNaN(double);public boolean isNaN();public static boolean isInfinite(double);public boolean isInfinite();public static boolean isFinite(double);public static double sum(double, double);public static double parseDouble(java.lang.String);public static final double POSITIVE_INFINITY;public static final double NEGATIVE_INFINITY;public static final double NaN;public static final double MAX_VALUE;public static final double MIN_NORMAL;public static final double MIN_VALUE;public static final int MAX_EXPONENT;public static final int MIN_EXPONENT;public static final int SIZE;public static final int BYTES;public static final java.lang.Class TYPE;private final double value;private static final long serialVersionUID; } */

    繼承的設計技巧

  • 將公共操作和字段放在超類中
  • 不要使用受保護的字段
  • 使用繼承實現"is-a"關系
  • 除非所有繼承方法都有意義, 否則不要使用繼承
  • 在覆蓋方法時,不要改變預期的行為
  • 使用多態, 而不要使用類型信息
  • 不要濫用反射

  • 總結

    以上是生活随笔為你收集整理的CoreJava 笔记总结-第五章 继承的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。