面向对象基础 1.class和instance class即类,instance即实例。
class是一种对象模版,它定义了如何创建实例,因此,class本身就是一种数据类型;
而instance是对象实例,instance是根据class创建的实例,可以创建多个instance,每个instance类型相同,但各自属性可能不相同。
2.实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package  oop;class  City  {         public  String name;     public  double  lattitude;     public  double  longitude; } public  class  oop1   {    public  static  void  main (String[] args)   {                  City frist = new  City();                  frist.name = "shanghai" ;         frist.lattitude = 11 ;         frist.longitude = 111 ;                  System.out.println(frist.name);         System.out.println(frist.lattitude);         System.out.println(frist.longitude);     } } 
 
3. 实例讲解 
City类中包含了3个字段(field,有些语言叫做属性),通过class我们实现了数据的封装 
public可以用来修饰方法和字段,表示其可以被外部访问 
创建实例用new,用Class名作为实例的数据类型 
访问实例属性时可以用变量.字段的形式,但是如果用private修饰了该属性则会报错 
 
方法 1.方法的引入 上一级中,我们直接把属性用public修饰,把属性暴露给外部可能会破坏封装性。所以我们往往采用private修饰属性,然后通过方法 来读取属性赋值
2.参数绑定 基本类型参数的传递,是调用方值的复制。双方各自的后续修改,互不影响
3.实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package  oop;public  class  opp2   {    public  static  void  main (String[] args)   {         Person Jhon = new  Person();                  Jhon.setBirth(2000 );         System.out.println(Jhon.getage());     } } class  Person  {         private  String name;     private  int  birth;          public  void  setBirth (int  birth)  {         this .birth = birth;     }     public  int  getage ()  {                  return  calcAge(2020 );     }          private  int  calcAge (int  currentYear)  {         return  currentYear - this .birth;     } } 
 
4.实例讲解 
public int getage()该语句中,public用于修饰方法是否供外部调用,int则是该方法的返回数据类型 
通过this.field就可以访问当前实例的字段,如果命名没有冲突实际上可以省略this 
this.birth = birth前一个birth指向实例的一个属性,后一个birth则是外部传入的参数,因为命名重复,所以要用this修饰 
 
构造方法 1.构造方法应用 创建对象实例时,我们可以使用构造方法让内部字段初始化,其相当于类内部一个和类同名的特殊的方法。
2.默认构造方法 如果一个类没有定义构造方法,编译器会为我们生成一个默认的构造方法,因而我们可以在new Person()调用
如果我们自定义了一个构造方法,那么默认的构造方法将不会被创建
3.实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package  oop;public  class  opp3   {    public  static  void  main (String[] args)   {                  Person2 ming = new  Person2("小明" , 21 );         System.out.println(ming.getAge());         System.out.println(ming.getName());     } } class  Person2  {    private  String name;     private  int  age;     public  String getName ()  {         return  name;     }     public  int  getAge ()  {         return  age;     } 	          public  Person2 (String name,int  age)  {         this .age = age;         this .name = name;     } } 
 
方法重载 1.方法重载介绍 在一个类中,如果存在一系列的方法功能方法名一样,但是参数不同。这种方法名相同,但各自的参数不同,称为方法重载(Overload)
方法重载参数不同,但是返回值类型通常相同
2.实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package  oop;public  class  opp4   {    public  static  void  main (String[] args)   {         Person4 ming = new  Person4();         ming.setName("xiao" , "ming" );         System.out.println(ming.getname());     } } class  Person4  {    private  String name;     public  String getname ()  {         return  name;     }     public  void  setname (String name)   {         this .name = name;     }     public  void  setName (String fname, String lname)   {         this .name = fname + lname;     } } 
 
继承 1.继承的应用 通过继承子类可以获得父类的所有功能,还可以在父类基础上编写额外的功能。
类自动获得了父类的所有字段,严禁定义与父类重名的字段
父类又可以称为超类,基类
子类又可以称为扩展类
2.继承树 除了object外,任何类都会继承于某个类,一个子类只能有一个父类,一个父类允许存在多个子类
3.protected与private 如果父类中的属性或方法是private修饰,子类同样也是无法访问到的,这时我们可以使用protected修饰,可以把属性和方法的权限控制在继承树内部
4.子类的构造方法 子类是无法继承父类的任何构造方法的,编译器会自动为我们添加super()来调用父类的构造方法,故若是父类存在带参数的构造方法,要手动在子类中调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public  class  Main   {    public  static  void  main (String[] args)   {         Student s = new  Student("Xiao Ming" , 12 , 89 );     } } class  Person   {    protected  String name;     protected  int  age;     public  Person (String name, int  age)   {         this .name = name;         this .age = age;     } } class  Student  extends  Person   {    protected  int  score;     public  Student (String name, int  age, int  score)   {                  super (name, age);         this .score = score;     } } 
 
7.向上转型与向下转型 (1)向上转型
1 2 3 4 Student s = new  Student(); Person p = new  Student(); 
 
这种把一个子类类型安全地变为父类类型的赋值,被称为向上转型(upcasting)
注意到继承树是Student > Person > Object,所以,可以把Student类型转型为Person,或者更高层次的Object
1 2 3 4 Student s = new Student(); Person p = s;  Object o1 = p; Object o2 = s; 
 
(2)向下转型
如果把一个父类类型强制转型为子类类型,就是向下转型(downcasting)
1 2 3 4 5 6 Person p1 = new  Student(); Person p2 = new  Person(); Student s1 = (Student) p1;  Student s2 = (Student) p2;  
 
6.实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 public  class  Main   {    public  static  void  main (String[] args)   {         Person p = new  Person("小明" , 12 );         Student s = new  Student("小红" , 20 , 99 );                  Student ps = new  PrimaryStudent("小军" , 9 , 100 , 5 );         System.out.println(ps.getScore());     } } class  Person   {    protected  String name;     protected  int  age;     public  Person (String name, int  age)   {         this .name = name;         this .age = age;     }     public  String getName ()   { return  name; }     public  void  setName (String name)   { this .name = name; }     public  int  getAge ()   { return  age; }     public  void  setAge (int  age)   { this .age = age; } } class  Student  extends  Person   {    protected  int  score;     public  Student (String name, int  age, int  score)   {         super (name, age);         this .score = score;     }     public  int  getScore ()   { return  score; } } class  PrimaryStudent  extends  Student    {    protected  int  grade;    	public  PrimaryStudent (String name, int  age, int  score, int  grade)  {                super (name, age, score);        this .grade = grade; } } 
 
多态 1.覆写 子类中不能存在与父类重名的属性,但子类可以覆写父类的方法,覆写方法时方法名和返回类型要相同
1 2 3 4 5 6 7 8 9 class  Person   {    public  void  run ()   {} } public  class  Student  extends  Person   {   	     @Override       public  void  run (String s)   {} } 
 
2.多态 Java的实例方法调用是基于运行时的实际类型的动态调用(new Student()),而非变量的声明类型(Person)
多态是指,针对某个类型的方法调用,其真正执行的方法取决于运行时期实际类型的方法
多态具有一个强大的功能——允许添加更多类型的子类实现功能扩展,却不需要修改基于父类的代码
3.实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 public  class  Main   {    public  static  void  main (String[] args)   {                  Income[] incomes = new  Income[] {             new  Income(3000 ),             new  Salary(7500 ),         };         System.out.println(totalTax(incomes));     }     public  static  double  totalTax (Income... incomes)   {         double  total = 0 ;                           for  (Income income: incomes) {             total = total + income.getTax();         }         return  total;     } } class  Income   {    protected  double  income;     public  Income (double  income)   {         this .income = income;     }     public  double  getTax ()   {         return  income * 0.1 ;      } } class  Salary  extends  Income   {    public  Salary (double  income)   {         super (income);     } 	          @Override      public  double  getTax ()   {         if  (income <= 5000 ) {             return  0 ;         }         return  (income - 5000 ) * 0.2 ;     } } 
 
4.多态补充 (1)调用父类中被覆写的方法用super
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class  Person   {    protected  String name;     public  String hello ()   {         return  "Hello, "  + name;     } } Student extends Person {     @Override      public  String hello ()   {                  return  super .hello() + "!" ;     } } 
 
(2)final修饰可以防止方法被子类覆写如:public final String hello()
抽象类 1.面向抽象编程 抽象类和其中的抽象方法本身是无法执行的,其强制了子类必须实现其定义的抽象方法,即相当于定义了一个规范
这种引用高层类型,避免引用子类型的方式,称为面向抽象编程
有以下优点:
上层代码只定义规范(例如:abstract class Person); 
不需要子类就可以实现业务逻辑(正常编译); 
具体的业务逻辑由不同的子类实现,调用者并不关心 
 
2.实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public  class  Main   {    public  static  void  main (String[] args)   {         Person p = new  Student();         p.run();     } } abstract  class  Person   {    public  abstract  void  run ()  ; } class  Student  extends  Person   {    @Override      public  void  run ()   {         System.out.println("Student.run" );     } } 
 
接口 1.接口介绍 接口(interface)中没有字段,接口中定义的所有方法默认为public abstract
2.接口实现 当用一个具体的class实现一个interface时,需要用到implements关键字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 interface  Person   {    void  run ()  ;     String getName ()  ; } class  Student  implements  Person   {    private  String name;     public  Student (String name)   {         this .name = name;     }     @Override      public  void  run ()   {         System.out.println(this .name + " run" );     }     @Override      public  String getName ()   {         return  this .name;     } } 
 
3.接口继承 接口也可以通过继承扩展
1 2 3 4 5 6 7 8 interface  Hello   {    void  hello ()  ; } interface  Person  extends  Hello   {    void  run ()  ;     String getName ()  ; } 
 
静态 1.静态字段 class中定义的字段我们称为实例字段,其一般有着独立性,各个实例间互不影响
但是如果我们用static一个静态修饰一个字段,那么所有的实例都会共享这个字段的空间
对于静态字段,我们无论修改哪个实例,所有实例的静态字段都会改动
我们往往采用类名.静态字段访问静态对象,如:Person.number = 99;
2.静态方法 静态方法可以通过类名直接调用,不需要一个实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public  class  Main   {    public  static  void  main (String[] args)   {         Person.setNumber(99 );         System.out.println(Person.number);     } } class  Person   {    public  static  int  number;          public  static  void  setNumber (int  value)   {         number = value;     } } 
 
3.接口的静态字段 因为接口是一个纯抽象类,所以它不能定义实例字段,但是可以有静态字段
1 2 3 4 5 public  interface  Person   {         int  MALE = 1 ;     int  FEMALE = 2 ; } 
 
包 位于同一个包的类,可以访问包作用域的字段和方法。不用public、protected、private修饰的字段和方法就是包作用域
可以用import语句导入其他包的class
作用域 可参考:https://www.liaoxuefeng.com/wiki/1252599548343744/12604662156765122