每一天的每一分每一秒都不晚!       2021年3月16日 23:18:07       

桐君过客

大三

Java学习_面向对象编程

  • 抽象类
    • 一个class定义了方法,但没有具体执行代码,这个方法就是抽象方法,抽象方法用abstract修饰。因为抽象类本身被设计成只能用于被继承,因此,抽象类可以强迫子类实现其定义的抽象方法,否则编译会报错。因此,抽象方法实际上相当于定义了“规范”。
    • 抽象方法的类都是抽象类,抽象类不全是抽象方法。
    • 面向抽象编程的本质就是:

      • 上层代码只定义规范(例如:abstract class Person);

      • 不需要子类就可以实现业务逻辑(正常编译);

      • 具体的业务逻辑由不同的子类实现,调用者并不关心。

  • 接口
    • 如果一个抽象类没有字段,且所有方法全部都是抽象方法,就可以把该抽象类改写为接口:interface
    • 接口中属性默认public static final 修饰  方法默认public abstract修饰
    • 一个具体的class去实现一个interface时,需要使用implements关键字。
    • 一个类可以实现多个interface。
    • 一个interface可以继承自另一个interfaceinterface继承自interface使用extends,它相当于扩展了接口的方法。
      1 interface Hello {
      2     void hello();
      3 }
      4 
      5 interface Person extends Hello {
      6     void run();
      7     String getName();
      8 }
      View Code
    • 在Java虚拟机执行的时候,JVM只看完整类名,因此,只要包名不同,类就不同。
    • 包没有父子关系。java.util和java.util.zip是不同的包,两者没有任何继承关系。
    • 位于同一个包的类,可以访问包作用域的字段和方法。不用publicprotectedprivate修饰的字段和方法就是包作用域
    • import

      • 直接写出完整类名 mr.jun.Arrays arrays = new mr.jun.Arrays();
      • import语句,导入Arrays,然后写简单类名。  
         1 // Person.java
         2 package ming;
         3 
         4 // 导入完整类名:
         5 import mr.jun.Arrays;
         6 
         7 public class Person {
         8     public void run() {
         9         Arrays arrays = new Arrays();
        10     }
        11 }
      • import static 包名 ,它可以导入一个类的静态字段和静态方法。

         1 package main;
         2 
         3 // 导入System类的所有静态字段和静态方法:
         4 import static java.lang.System.*;
         5 
         6 public class Main {
         7     public static void main(String[] args) {
         8         // 相当于调用System.out.println(…)
         9         out.println("Hello, world!");
        10     }
        11 }
      • 如果是简单类名,按下面的顺序依次查找:

        • 查找当前package是否存在这个class

        • 查找import的包是否包含这个class

        • 查找java.lang包是否包含这个class

      •   因此,编写class的时候,编译器会自动帮我们做两个import动作:
        • 默认自动import当前package的其他class

        • 默认自动import java.lang.*

        • 自动导入的是java.lang包,但类似java.lang.reflect这些包仍需要手动导入。
        • 如果有两个class名称相同,例如,mr.jun.Arraysjava.util.Arrays,那么只能import其中一个,另一个必须写完整类名。
  • 内部类
    • 普通类有个最大的不同,就是Inner Class的实例不能单独存在,必须依附于一个Outer Class的实例。
       1 public class Main {
       2     public static void main(String[] args) {
       3         Outer outer = new Outer("Nested"); // 实例化一个Outer
       4         Outer.Inner inner = outer.new Inner(); // 实例化一个Inner
       5         inner.hello();
       6     }
       7 }
       8 
       9 class Outer {
      10     private String name;
      11 
      12     Outer(String name) {
      13         this.name = name;
      14     }
      15 
      16     class Inner {
      17         void hello() {
      18             System.out.println("Hello, " + Outer.this.name);
      19         }
      20     }
      21 }
    • Inner Class和普通Class相比,除了能引用Outer实例外,还有一个额外的“特权”,就是可以修改Outer Class的private字段,因为Inner Class的作用域在Outer Class内部,所以能访问Outer Class的private字段和方法。(Inner Class除了有一个this指向它自己,还隐含地持有一个Outer Class实例,可以用Outer.this访问这个实例。)
    • 匿名内部类
      •   不需要在Outer Class中明确地定义这个Class,而是在方法内部,通过匿名类(Anonymous Class)来定义。
         1 public class Main {
         2     public static void main(String[] args) {
         3         Outer outer = new Outer("Nested");
         4         outer.asyncHello();
         5     }
         6 }
         7 
         8 class Outer {
         9     private String name;
        10 
        11     Outer(String name) {
        12         this.name = name;
        13     }
        14 
        15     void asyncHello() {
        16         Runnable r = new Runnable() {        //重写父类或者接口的方法
        17             @Override
        18             public void run() {
        19                 System.out.println("Hello, " + Outer.this.name);
        20             }
        21         };
        22         new Thread(r).start();
        23     }
        24 }
    •    静态内部类
      •  1 public class Main {
         2     public static void main(String[] args) {
         3         Outer.StaticNested sn = new Outer.StaticNested();   //外部类无需实例化
         4         sn.hello();
         5     }
         6 }
         7 
         8 class Outer {
         9     private static String NAME = "OUTER";
        10 
        11     private String name;
        12 
        13     Outer(String name) {
        14         this.name = name;
        15     }
        16 
        17     static class StaticNested {
        18         void hello() {
        19             System.out.println("Hello, " + Outer.NAME);
        20         }
        21     }
        22 }
      • static修饰的内部类和Inner Class有很大的不同,它不再依附于Outer的实例,而是一个完全独立的类,因此无法引用Outer.this,但它可以访问Outerprivate静态字段和静态方法。如果把StaticNested移到Outer之外,就失去了访问private的权限。
  • classpath和jar

    • classpath和jar
    • 图1
    • 图2 
  • 模块
  • 多态 
    • 在继承关系中,子类如果定义了一个与父类方法签名完全相同的方法,被称为覆写(Override)。
    • Java的实例方法调用是基于运行时的实际类型的动态调用,而非变量的声明类型。(多态
    • public void runTwice(Person p) {
          p.run();
          p.run();
      }

      它传入的参数类型是Person,我们是无法知道传入的参数实际类型究竟是Person,还是Student,还是Person的其他子类,因此,也无法确定调用的是不是Person类定义的run()方法。

  • 覆写Object方法

    • toString():把instance输出为String
    • equals():判断两个instance是否逻辑相等;Java equals方法学习
    • hashCode():计算一个instance的哈希值。
  • 在子类的覆写方法中,如果要调用父类的被覆写的方法,可以通过super来调用。
    class Person {
        protected String name;
        public String hello() {
            return "Hello, " + name;
        }
    }
    
    Student extends Person {
        @Override
        public String hello() {
            // 调用父类的hello()方法:
            return super.hello() + "!";
        }
    }
  • 方法标记为final。用final修饰的方法不能被Override
  • 类本身标记为final。用final修饰的类不能被继承:
  • final修饰的字段(包括局部变量)在初始化后不能被修改。
    • 可以在构造方法中初始化final字段123
      1 class Person {
      2     public final String name;
      3     public Person(String name) {
      4         this.name = name;
      5     }
      6 }
  • 抽象类
    • 一个class定义了方法,但没有具体执行代码,这个方法就是抽象方法,抽象方法用abstract修饰。因为抽象类本身被设计成只能用于被继承,因此,抽象类可以强迫子类实现其定义的抽象方法,否则编译会报错。因此,抽象方法实际上相当于定义了“规范”。
    • 抽象方法的类都是抽象类,抽象类不全是抽象方法。
    • 面向抽象编程的本质就是:

      • 上层代码只定义规范(例如:abstract class Person);

      • 不需要子类就可以实现业务逻辑(正常编译);

      • 具体的业务逻辑由不同的子类实现,调用者并不关心。

  • 接口
      • 如果一个抽象类没有字段,且所有方法全部都是抽象方法,就可以把该抽象类改写为接口:interface
      • 接口中属性默认public static final 修饰  方法默认public abstract修饰
      • 一个具体的class去实现一个interface时,需要使用implements关键字。
      • 一个类可以实现多个interface。
      • 一个interface可以继承自另一个interfaceinterface继承自interface使用extends,它相当于扩展了接口的方法。
        View Code
      • 在Java虚拟机执行的时候,JVM只看完整类名,因此,只要包名不同,类就不同。
      • 包没有父子关系。java.util和java.util.zip是不同的包,两者没有任何继承关系。
      • 位于同一个包的类,可以访问包作用域的字段和方法。不用publicprotectedprivate修饰的字段和方法就是包作用域
      • import

        • 直接写出完整类名 mr.jun.Arrays arrays = new mr.jun.Arrays();
        • import语句,导入Arrays,然后写简单类名。  
           1 // Person.java
           2 package ming;
           3 
           4 // 导入完整类名:
           5 import mr.jun.Arrays;
           6 
           7 public class Person {
           8     public void run() {
           9         Arrays arrays = new Arrays();
          10     }
          11 }
        • import static 包名 ,它可以导入一个类的静态字段和静态方法。

           1 package main;
           2 
           3 // 导入System类的所有静态字段和静态方法:
           4 import static java.lang.System.*;
           5 
           6 public class Main {
           7     public static void main(String[] args) {
           8         // 相当于调用System.out.println(…)
           9         out.println("Hello, world!");
          10     }
          11 }
        • 如果是简单类名,按下面的顺序依次查找:

          • 查找当前package是否存在这个class

          • 查找import的包是否包含这个class

          • 查找java.lang包是否包含这个class

        •   因此,编写class的时候,编译器会自动帮我们做两个import动作:
          • 默认自动import当前package的其他class

          • 默认自动import java.lang.*

          • 自动导入的是java.lang包,但类似java.lang.reflect这些包仍需要手动导入。
          • 如果有两个class名称相同,例如,mr.jun.Arraysjava.util.Arrays,那么只能import其中一个,另一个必须写完整类名。

内部类

      • 普通类有个最大的不同,就是Inner Class的实例不能单独存在,必须依附于一个Outer Class的实例。
         1 public class Main {
         2     public static void main(String[] args) {
         3         Outer outer = new Outer("Nested"); // 实例化一个Outer
         4         Outer.Inner inner = outer.new Inner(); // 实例化一个Inner
         5         inner.hello();
         6     }
         7 }
         8 
         9 class Outer {
        10     private String name;
        11 
        12     Outer(String name) {
        13         this.name = name;
        14     }
        15 
        16     class Inner {
        17         void hello() {
        18             System.out.println("Hello, " + Outer.this.name);
        19         }
        20     }
        21 }
      • Inner Class和普通Class相比,除了能引用Outer实例外,还有一个额外的“特权”,就是可以修改Outer Class的private字段,因为Inner Class的作用域在Outer Class内部,所以能访问Outer Class的private字段和方法。(Inner Class除了有一个this指向它自己,还隐含地持有一个Outer Class实例,可以用Outer.this访问这个实例。)
      • 匿名内部类
        •   不需要在Outer Class中明确地定义这个Class,而是在方法内部,通过匿名类(Anonymous Class)来定义。
           1 public class Main {
           2     public static void main(String[] args) {
           3         Outer outer = new Outer("Nested");
           4         outer.asyncHello();
           5     }
           6 }
           7 
           8 class Outer {
           9     private String name;
          10 
          11     Outer(String name) {
          12         this.name = name;
          13     }
          14 
          15     void asyncHello() {
          16         Runnable r = new Runnable() {        //重写父类或者接口的方法
          17             @Override
          18             public void run() {
          19                 System.out.println("Hello, " + Outer.this.name);
          20             }
          21         };
          22         new Thread(r).start();
          23     }
          24 }
      •    静态内部类
        •  1 public class Main {
           2     public static void main(String[] args) {
           3         Outer.StaticNested sn = new Outer.StaticNested();   //外部类无需实例化
           4         sn.hello();
           5     }
           6 }
           7 
           8 class Outer {
           9     private static String NAME = "OUTER";
          10 
          11     private String name;
          12 
          13     Outer(String name) {
          14         this.name = name;
          15     }
          16 
          17     static class StaticNested {
          18         void hello() {
          19             System.out.println("Hello, " + Outer.NAME);
          20         }
          21     }
          22 }
        • static修饰的内部类和Inner Class有很大的不同,它不再依附于Outer的实例,而是一个完全独立的类,因此无法引用Outer.this,但它可以访问Outerprivate静态字段和静态方法。如果把StaticNested移到Outer之外,就失去了访问private的权限。

 

  • classpath和jarclasspath和jar

 

posted @ 2020-12-23 23:01  桐君过客  阅读(112)  评论(0)    收藏  举报