Java学习_面向对象编程
- 抽象类
- 一个
class定义了方法,但没有具体执行代码,这个方法就是抽象方法,抽象方法用abstract修饰。因为抽象类本身被设计成只能用于被继承,因此,抽象类可以强迫子类实现其定义的抽象方法,否则编译会报错。因此,抽象方法实际上相当于定义了“规范”。 - 抽象方法的类都是抽象类,抽象类不全是抽象方法。
-
面向抽象编程的本质就是:
-
上层代码只定义规范(例如:
abstract class Person); -
不需要子类就可以实现业务逻辑(正常编译);
-
具体的业务逻辑由不同的子类实现,调用者并不关心。
- 一个
- 接口
- 如果一个抽象类没有字段,且所有方法全部都是抽象方法,就可以把该抽象类改写为接口:
interface。 - 接口中属性默认public static final 修饰 方法默认public abstract修饰
- 一个具体的
class去实现一个interface时,需要使用implements关键字。 - 一个类可以实现多个
interface。 - 一个
interface可以继承自另一个interface。interface继承自interface使用extends,它相当于扩展了接口的方法。
View Code1 interface Hello { 2 void hello(); 3 } 4 5 interface Person extends Hello { 6 void run(); 7 String getName(); 8 }
- 如果一个抽象类没有字段,且所有方法全部都是抽象方法,就可以把该抽象类改写为接口:
- 包
- 在Java虚拟机执行的时候,JVM只看完整类名,因此,只要包名不同,类就不同。
- 包没有父子关系。java.util和java.util.zip是不同的包,两者没有任何继承关系。
- 位于同一个包的类,可以访问包作用域的字段和方法。不用
public、protected、private修饰的字段和方法就是包作用域。 -
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.Arrays和java.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 }
- 不需要在Outer Class中明确地定义这个Class,而是在方法内部,通过匿名类(Anonymous Class)来定义。
- 静态内部类
-
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,但它可以访问Outer的private静态字段和静态方法。如果把StaticNested移到Outer之外,就失去了访问private的权限。
-
- 普通类有个最大的不同,就是Inner Class的实例不能单独存在,必须依附于一个Outer Class的实例。
-
classpath和jar
classpath和jar-
- 图1

- 图2

- 图1
- 模块
- 多态
- 在继承关系中,子类如果定义了一个与父类方法签名完全相同的方法,被称为覆写(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 }
- 可以在构造方法中初始化final字段123
- 抽象类
- 一个
class定义了方法,但没有具体执行代码,这个方法就是抽象方法,抽象方法用abstract修饰。因为抽象类本身被设计成只能用于被继承,因此,抽象类可以强迫子类实现其定义的抽象方法,否则编译会报错。因此,抽象方法实际上相当于定义了“规范”。 - 抽象方法的类都是抽象类,抽象类不全是抽象方法。
-
面向抽象编程的本质就是:
-
上层代码只定义规范(例如:
abstract class Person); -
不需要子类就可以实现业务逻辑(正常编译);
-
具体的业务逻辑由不同的子类实现,调用者并不关心。
-
- 一个
- 接口
-
- 如果一个抽象类没有字段,且所有方法全部都是抽象方法,就可以把该抽象类改写为接口:
interface。 - 接口中属性默认public static final 修饰 方法默认public abstract修饰
- 一个具体的
class去实现一个interface时,需要使用implements关键字。 - 一个类可以实现多个
interface。 - 一个
interface可以继承自另一个interface。interface继承自interface使用extends,它相当于扩展了接口的方法。
View Code
- 如果一个抽象类没有字段,且所有方法全部都是抽象方法,就可以把该抽象类改写为接口:
-
- 包
-
- 在Java虚拟机执行的时候,JVM只看完整类名,因此,只要包名不同,类就不同。
- 包没有父子关系。java.util和java.util.zip是不同的包,两者没有任何继承关系。
- 位于同一个包的类,可以访问包作用域的字段和方法。不用
public、protected、private修饰的字段和方法就是包作用域。 -
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.Arrays和java.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 }
- 不需要在Outer Class中明确地定义这个Class,而是在方法内部,通过匿名类(Anonymous Class)来定义。
- 静态内部类
-
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,但它可以访问Outer的private静态字段和静态方法。如果把StaticNested移到Outer之外,就失去了访问private的权限。
-
- 普通类有个最大的不同,就是Inner Class的实例不能单独存在,必须依附于一个Outer Class的实例。
-
-
classpath和jar
classpath和jar
-
-
- 图1

- 图2

- 图1
-
- 模块

浙公网安备 33010602011771号