=============类和对象 ======================
 
 类:类是同一类事物的总称。
对象:现实世界中实实在在存在的事物。
类和对象的关系:类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的一类实体称为类。如鸟类有鸵鸟、大雁、麻雀等。鸵鸟、大雁、麻雀被称为鸟类的实体,即对象。
 
面向对象:对象所共有的功能和属性进行抽像,成为了类。客观事物在人脑中的主观反映。在程序里类是创建对象的模板。  
面向对象程序设计的特点:封装性、继承性、多态性。

类成员:成员变量(属性)和成员方法(行为)。
定义成员方法的格式:权限修饰符 返回值类型 方法名(参数类型 参数名)
               {方法体 return返回值} 成员方法需要返回值时使用关键字 return
 
java中的对象 :对现实对象的抽象(获得有用的,舍弃没用的)。
      存储空间中的一块数据区域,用于存数据。如:人(nama sex age)
       属性:实例变量(定义在类以内,方法之外)  
            1.默认的初值
            2.实例变量的使用范围至少是类以内
            3.实例变量调用必须有对象,实例变量和局部变量重名,局部优先。
               
例:
public class Test{
      public static void main(String[] args){
      
      //新建对象stu;stu存的是新建对象stu的地址。stu的专业术语:引用/对象变量/引用变量/实例变量
           Student stu=new Student();        
           stu.name="tom";       //给对象stu的name属性赋值。
      }}
class Student{              //用类声明的数据(str)为引用类型,如:Student str;
 
      //实例变量:定义在方法之外,类以内的,没有static修饰的变量
      //实例变量会有一个默认的初始值。初始值与变量定义时的类型有关。
      //实例变量(成员变量)--->属性。可通过新建对象的引用来访问类的实例变量。如,stu.name;
      String name;     
      int age;
      String sex;
}
实例变量和局部变量的区别:
1,位置:局部变量定义在方法里面。实例变量定义在类以内方法之外。
2,使用的范围:局部变量只能在定义他的方法里面使用,直接调用变量名就可以了。
      实例变量至少可以在定义他的整个类内使用,使用时必须用对象去调用。只有跟对象一起实例变量才有意义。
3,局部变量使用之前必须初始化。实例变量不需要赋初值,系统会给默认的初值。
 
4,局部变量在同一方法里不能重名。局部变量和实例变量可以重名,在方法里采用就近原则。
 
=================方法:=============
包括:
      方法: 
       做什么:方法的定义  
           修饰符   返回类型   方法名(参数列表) 异常
       怎么做:方法的实现 {******}          
修饰符(如:public)  返回类型(如:int) 方法名/函数名(参数表--形参)          
如:
      public void eat(String fish){                //eat(),吃的功能。
           //怎么做.
      }
使用实例方法时也需要用对象去调用。如:stu.eat("fish");
 
======构造方法====== 
 
功能:创建其所属类型的一个新的对象。(构造方法无返回值类型)
语法格式:
< modifiers修饰符>  <class_name类名>([< argu_list>]) {
          [< statements>]  方法体
} 
举例:
–class Person {
int age;
Person() { age = 18; }
Person(inti) { age = i; }
void setAge(inti) { age = i; }
–}  
Java语言中,每个类都至少有一个构造方法;
如果类的定义者没有显式的定义任何构造方法,系统将自动提供一个默认的构造方法:
–默认构造方法没有参数
–默认构造方法没有方法体
Java类中,一旦类的定义者显式定义了一个或多个构造方法,系统将不在提供默认的构造方法;每个子类的构造方法里都有一个父类的默认构造方法,即super(),注意:前提是父类没有显示的构造方法,当父类有一个或多个显示构造方法时,子类的构造方法要想调用,必须在方法体第一行加上 super(参数类型)。
 
 
 
方法重载(overloading):编译时多态。
在一个类的内部,方法名相同形参数不同的方法,对返回类型不要求,这种现象称之为重载;
编译器会自动选择使用的方法。体现了一个编译时多态。
好处:对使用者屏蔽因为参数不同造成方法间的差异。
找方法时如果没有合适的,采取自动向上扩展原则。
调用时形参之间的区别一定要明确。
    1. 形参的个数不同
    2. 形参的类型不同
    3. 形参的顺序不同
    4. 形参的名字相同
 
方法覆盖(override):运行时多态。
1,发生在父类和子类之间
2,方法名相同,参数相同,返回类型相同
3,子类方法的访问权限不能更严格,只能等于或更加宽松。
 
构造方法:
1,没有返回类型,方法名必须和类同名。
2,构造方法不能手动调用,它只用在创建对象在时候,只出现在new之后。
      只要构造方法被调用运行,就一定有对象产生。
3,在一个对象的生命周期里,构造方法只能被调用一次。
4,类写好后一定有构造方法,
      如果程序没有显示的提供构造方法,JVM会提供一个默认的构造方法,public classname(){}
      如果程序显示提供,系统不再提供默认的
5,同一个类的多个构造方法一定重载。
6,创建对象的同时构造方法的代码块里还可以写需要运行的代码,还可以给属性(实例变量)赋值,
      引用类型的属性赋值就是用new创建对象,然后调用构造方法。如:Student stu=new Student();
用new创建对象时JVM做的三件事:
如:Student stu=new Student();
1,申请空间;(把值放到空间里,再把空间的地址给引用变量。)----创建父类对象
2,初始化实例变量;没显示声明值的话就用默认值。
3,执行构造方法,
因为实例变量在创建对象的过程中被初始化,所以使用实例变量前必须创建对象(要用对象去调用),否则实例变量根本不存在
 
=====关键字:this=======
1,在普通方法里,指代当前对象引用(哪个对象调用该方法,this就指向该对象)
2,this不能出现在静态方法里。
3,在构造方法里,this用来指代本类的其他构造方法。在本类构造方法之间互相调用。如:this(形参);
      使用时放在构造方法里的第一行。
4,不能写成死循环(不能递归调用)
=====关键字:super=======
(和this的用法类似)
1,调用父类的构造方法,在子类调用父类的构造方法必须出现在第一句,构造方法第一句可能出现的三种情况(调用父类的构造方法看子类构造方法的第一句)①super();②super(参数)注意传递的参数一定是实体,有值的。③this(),先在本类的构造方法间调用,再看调用那个构造方法的第一句是什么
2,super访问父类的变量和方法,及super代表父类的对象,super.name;super.setName();
注意:this 和super关键字不能同时存在在方法体中。
======参数传递========
1,参数相当于局部变量
2,参数传递相当于赋值语句
3,基本类型数据传递的是本身的值,引用类型数据传递的是引用xx(Animal animal)(地址,对象变量本身的值)
 
面向对象的三大特性:
 
一,封装(Encapsulation):一个系统以合理的粒度出现。
定义:封装就是将客户端不应看到的信息包裹起来。使内部执行对外部来看不一种不透明的、是一个黑箱,客户端不
 
需要内部资源就能达到他的目的。(封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象
计算始于这个基本概
念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。)
1.事物的内部实现细节隐藏起来
 
2.对外提供一致的公共的接口――间接访问隐藏数据         3.可维护性  
访问控制修饰符:public(公开的),protected(受保护的,1,本包内可见;2,其他包的子类可见)
                        default(默认,本包内可见),private(私有的,类内部可见)
访问控制修饰符   (可以范围)          (可修饰)下面的类(指外部类)
      private         本类            方法,属性
      default         本包            类,方法,属性
      protected     本包+子类                方法,属性
      public         到处可见          类,方法,属性
 
1,属性:隐藏所有属性,用private。隐藏后属性只能在类以内访问 。程序可以根据需要提供get和set
2,方法(函数):该公开的公开,该私有的就私有。(视情况而定)
3,公开方法的功能,隐藏方法的实现细节。
 
二,继承(inheritance):抽象出不变性。
从一般到特殊的关系,可以设计成继承
   特点:共性写在父类里面,特性写在子类
所有类的总父类是Object (Object是类的祖先)
父类里写的是共性,子类里写的是特性。
父类中用private修饰的属性和方法不能被子类继承;
但是父类里的属性子类都有,如果子类有特殊属性的话,就要在子类里定义
且在创建该子类对象的时候初始化属性(包括父类所有属性和该子类所有属性);
 
什么样的功能和属性可以继承到子类?
对于父类里的属性和方法,子类有权访问的,我们称为可以继承;
 
用new创建子类对象,JVM执行的过程:Dog d=new Dog(); 为d申请空间。class Dog extends Animal{}    
(1)申请空间;(把值放到空间里,再把空间的地址给引用变量。)
(2)看本类构造方法的第一句
(3)默认的创建父类对象:
      执行顺序:子类(2)--->  父类(2-->3-->4-->5)--->   子类(4-->5),
      新建一个对象空间只申请一次(该空间存放所有父类和子类)。)
(4)初始化本类的实例变量(该类的所有属性);
(5)执行本类的构造方法,(构造方法只会在创建一个对象的时候被执行一次)
 
(创建是先执行父类的构造方法,在执行子类的构造方法,访问时先访问子类自己的特殊属性和方法再访问父类的属
性和方法)
用super调用父类被子类覆盖的普通方法和遮盖的属性
,
指代的是在创建子类对象过程中,由JVM自动创建的那个父类,如:super.方法名()/属性
 
用super调用父类的构造方法;必须出现在子类构造方法的第一句。如:super(形参);
 
1,在子类的构造方法里如果没有指明调用哪一个父类的构造方法(就是子类中没有super(形参)语句;),
 
      JVM会默认调用父类的无参构造方法,跟本类构造方法的形参没有关系。
 
2,显示的写super,JVM会根据参数调用相应的父类构造方法。
 
3,有this(形参),在本类的构造方法之间调用,看被调用的那个构造方法的第一行。
 
 
 
 三,多态(polymorphism):多态只有方法多态,没有属性多态。
用父类类型屏蔽子类之间的差异
 
所有的子类对象都可以当父类对象来用,一个父类型的引用可能指向的是一个子类对象,
如:把狗(对象)看作动物(类型)。Animal a=new Dog();               编译看前面,运行看后面。
                            (编译时类型)   (运行时类型)
1,运行时对象不会改变(对象是客观存在的),如:狗这个对象的属性和方法是不会改变的。
2,对一个引用,只能调用编译时类型里的已知方法。
      如:编译器知道动物里已有的属性和方法,但不知道狗的属性和方法。
3,运行时会根据运行时类型自动寻找覆盖过的方法运行。
 
引用  instanceof 类名         
  instanceof是Java的一个二元操作符,和==,>,<是同一类东西。
  由于它是由字母组成的,所以也是Java的保留关键字。
  它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。
 
//结果为boolean值,
引用所指向的对象和类名类型是否一致(对象是否属于类名类型)
类型的转换:转换编译时类型
   Sub  su= (Sub) s;
   子类型的引用向父类型转换时,不需要强转
   父类型的引用向子类型转换时,需要强转                                                     
     Animal a=new Cat();
     Dog d=(Dog)a;      // 类型转换异常 
     引用  instanceof  类名 -----> boolean
     引用所指向的对象和类名所代表的类型是否一致   
     a instanceof Animal ----->  true      a instanceof Cat---------->  true    a instanceof Dog----------->false
     Employee e=new Manager();
     e instanceof Employee ------>true
     e instanceof Manager------> true     
     
 属性没有多态,属性只看编译时类型
 
    
编写程序的顺序:
class 类名{
      private属性(有什么)
      无参的构造方法(public类名(){})
      有参的构造方法(作用:给属性赋值)
      set和get(设置和获得属性)
      业务方法(做什么)
}
 
一,修饰符:static 
      static变量:如:static int index=2;
           类的所有对象共同拥有的一个属性;可以用类名直接访问,又称为类变量,
           类的所有对象共同拥有的一个变量;类第一次被加载时会初始化静态变量
(也就是会先执行static修饰的变量);
           跟类创建了多少对象无关;任何对象对静态变量做的修改,其他对象看到的是修改后的值。
            可以用作计数器,记录类创建对象的个数, static变量在类加载的时候只会被初始化一次,
      static方法:如:public static void teach(){}
           可以用类名直接去调用,不需要对象所以不能直接访问(在没有对象的情况下)实例变量,
在静态方法里不能出现this和super,类的所有对象共同拥有的一个方法;跟类创建了多少
 
对象无关。
           在继承里,父类的静态方法只能被子类的静态方法覆盖,且覆盖以后没有多态
(访问的是父类的静态方法);
      static初始化块:如:class Teacher(){
                                  static int index=4;
                                  static{          //static初始化块
                                       .........
                                       }
                                  }
      静态初始化块:用static修饰类里面的一个独立的代码块,类第一次被JVM加载的时候执行,只
被执行一次。
      类加载:JVM在第一次使用一个类时,会到classpath所指定的路径去找这个类所对应的字节码文件,
           并读进JVM保存起来,这个过程称之为类加载,一个线程一个jvm。
  
      
二,final  (最后的,最终的)final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承
      final类:如:final class Animal{}
           表示该类不能被继承,意味着不能改变里面的代码;
           对虚拟机的正常运行有重要作用的类通常用final修饰,如:String,System,Math ...等类
      final方法:如:public final void sleep(){}       该方法不能被覆盖(修改),但能被子类访问。
                      
      
      final变量:如:final (static) int index=4;
                      该变量是常量能被继承(访问);
                      final修饰的变量就是常量,通常和static一起连用,来声明常量;
                      final修饰引用类型数据,指的是引用(地址)不能变,但引用里的数据不受限制。
                      final修饰的变量,只要在初始化的过程中就可以赋值。
 
                      实例变量:声明的同时或构造方法里赋值;
                      静态变量:声明的同时或在静态代码块里赋值;
 
三,abstract
      abstract类:如:abstract class Animal{}
                      抽象类,不能创建对象(如一些父类),但是可以声明一个抽象类型的引用
                      (可以声明父类类型子类对象,编译时利用多态调用抽象方法)。
                      含有抽象方法的类一定是抽象类,但抽象类并不一定要有抽象方法;
                      抽象类一般是用来被继承的;子类继承自抽象类,就要实现里面的抽象方法,
                      如果不想让子类也是抽象类的话,必须实现父类里面所有的抽象方法。
                      抽象类有构造方法,有父类,也遵循单继承的规律。
      
      abstract方法:如:public abstract void sleep();
           抽象方法,只有方法名的定义,没有实现体(只定义了能做什么,没定义怎么做),不能被调用,
                      用于被子类的方法覆盖或重新实现。只能放在抽象类中。
                      好处:允许方法的定义和实现分开。
                      public  protected  default  private  static final  abstract
                   可以: public static 
                           private static 
                          public final
                          public static final
                 不可以:abstract final void eat();  
                 private abstract void eat();
                 static abstract void eat();
            abstract不能和final,private,static连用。
 
四,interface:是抽象类的变体,。在接口中,所有方法都是抽象的。如:interface M{
                                       int num=3;
                                       void eat();
                                  }
      理解为接口是一个特殊的抽象类,所以接口不能创建对象,且接口没有构造方法,
      但可以声明一个接口类型的引用(m是接口类型实现类对象,如:M m=new N();)
      接口存在的意义是被子类实现,如果不想让子类也抽象,
      就要实现接口里面所有的抽象方法,实现过程中注意访问权限;
 
      用  implements 关键字实现接口,如:class N implements M{
                                                  public void eat(){...}
                                                }
      接口里面的常量默认都是public static final的;
      接口里面的方法默认都是public abstract的。
      
      接口本身支持多继承,继承了父接口里功能的定义,如,interface A extends B,C,D{}        //A,B,C,D都是接口;
      类可以同时继承一个父类和实现接口(或多个接口)。
      如:class AA extends BB implements CC,DD,EE{}//AA,BB      是类,CC,DD,EE是接口;
      作用:1,用接口去实现多继承,接口是对类的共性进行再次抽象,抽象出类的次要类型。
                 如:蜘蛛侠,拥有人和蜘蛛的属性,但主要类型是人,次要类型(接口)是蜘蛛,
                 因为接口是次要类型,所以在类关系里不占一个节点,不会破坏类层次关系的树状结构,
             2,标准(保证弱耦合):一个接口就是一个标准(里面的属性不能改变,只定义了功能,
但没有被实现),  接口将标准的制定者,标准的实现者以及标准的使用者分离开,
                 降低实现者和使用者的耦合。接口是java里一种重要的降低耦合的工具;
接口可以屏蔽不同实现类的差异,
                 当底层的实现类更换后,不会对上层的使用者产生影响,体现在参数和返回值。   
                 
                 写程序时,应该先写实现者再写使用者,如:Bank.java是实现者,View.java是使用者,
                 但是有了接口之后,就可以用接口回调的功能;
                 接口回调:先定义接口,然后写使用者和实现者的顺序随便(一般是先写使用者,
后写实现者);利用参数把实现者传给使用者(即:实现者是使用者的属性),
使用者利用接口调用实现者相应的功能。
       **接口和抽象类的区别1一个类可以implements多个接口,而只能extends一个抽象类
                       2,一个抽象类可以实现部分的方法,而接口都是抽象的方法和属性
 
Object是Java里所有类的直接或间接父类,Object类里面的所有功能是所有java类共有的
1,JVM调用垃圾回收器回收不用的内存(没有引用指向的对象)前运行finalize(),给JVM用的方法。
      程序显示的通知JVM回收没用的内存(但不一定马上就回收):System.gc();或    Runtime.getRuntime().gc();
 
2,toString()返回对象的字符串表现形式,打印对象时,虚拟机会自动调用toString获取对象的字符串表现格式,
      如:System.out.println(str.toString());      ==System.out.println(str);
      如果本类不提供(覆盖)toString(),那么使用的是Object类里的相应方法,打印的就是地址。
      如:public String toString(){
                 return ".....";
           }
           
3,基本类型时“==“判断变量本身的值是否相等;引用类型时,判断的是地址是否相等。
      equals判断的是对象内容是否相等。对于自己创建的类,应该覆盖Object类的equals()方法;
      否则使用的是Object类里的equals()方法,比的是地址。
      
      覆盖方法如下:
      /*****************************************************
      public boolean equals(Object o){  
        if(o==null)  return false;
        if(o==this)  return true;
        if(!(o.getClass()==this.getClass())) return false;
        final Student s=(Student)o;
        return this.name.equals(s.name) && this.age==s.age ;  //比较原则;
      }  
    ******************************************************/
      覆盖euqals()方法时遵循的原则:
      自反性:a.quals(a);         //true
      对称性:a.equals(b);<==> b.equals(a);      //true
      传递性:a.equals(b);//true         b.equals(c); //true
           --->则:a.equals(c);  //为true                
      
封装类(Wrapper class):
OverLoading时,基本类型时采用向上匹配原则,
如果没有基本类型的话就向包装类转换,如果还没有就让这个基本类型在包装类里也采用向上匹配原则;
 
基本类型-转换到-->包装类
boolean----->Boolean
int-------->Integer      //Integer是引用类型,
int-------->Ddouble           //合法,         但Integer------>Double    非法
double------>Double
   ......  ------->   ......
任何类型----->Object
基本数据类型int可以向double自动扩展,但是包装类型之间不能自动的相互转换,
基本类型数据--->包装类型
int i=3;
Integer it=new Integer(i);        //手动转换;基本类型向包装类型转换。
int <----> Integer <----> String
转换时String类型必须为全数字字符串。如:"2515"    不能为:"abc265","aec"...等
String str=”123”; int it=Integer,parseInt(str);把字符串转换成数字。String str2=it+“”;把数字转化成字符串
 
==内部类============
定义在其他代码块(类体或者方法体)里的类称为内部类;
编译后每一个内部类都会有自己的独立的字节码文件,
文件名:Outer$Inner.class-->内部类也可以有父类和实现接口。也可以有抽象方法。
 
根本位置和修饰符的不同分为四种:
1,member inner class       成员内部类,当实例方法或变量一样理解。
      1)定义的位置:类以内,方法之外,没有静态修饰符(static)。
      2)本身能定义的属性和方法:只能定义非静态的属性和方法。
      3)能直接访问的什么:能访问外部类的所有静态和非静态的属性或方法。
      4)怎么创建对象:在外部类内的方法内:Outer.Inner inner=new Outer().new Inner();
            在外部类外的类的方法内:Outer.Inner inner=new Outer().new Inner();或
在Outer类里提供一个getInner()方法,返回内部类的对象,这样在外部类外的类的方法内也可以用该成员内部类。
      
2,static inner class 静态内部类(嵌套内部类),当静态方法或变量一样理解。
      static只能修饰内部类,不能修饰外部类。
      1)定义的位置:类以内,方法之外,有静态修饰符(static)。一般写在外部类的属性下面。
      2)本身能定义的属性和方法:可以定义静态和非静态的属性或方法。
      3)能直接访问的什么:只能访问外部类的静态属性和方法。
      4)怎么创建对象:在外部类内的方法里: Outer.Inner inner=new Outer.Inner();
                                 在外部类外的类方法里:   Outer.Inner inner=new Outer.Inner();
3,local inner class        局部内部类           当局部变量一样理解。
      1)定义的位置:方法里面的类,前面不能用public或static修饰。
      2)本身能定义的属性和方法:只能定义非静态的属性和方法。
      3)能直接访问的什么:能访问方法内用final修饰的局部变量(不能与该类内的变量名相同)。
                                       能访问外部类的所有静态和非静态的属性或方法。
      4)怎么创建对象:只能在方法内创建对象,如:Inner inner=new Inner(); 对象的作用范围只在方法内。
4,annonymous inner class         匿名内部类                       如:  Teacher tc=new Teacher(){
      1)没有名字的类,没有构造方法。是一个特殊的局部内部类,                 public void teach(){...}
             可以实现一个接口,   或者一个类,                                            }
             生命周期里只能产生一个对象(tc),也就是说只能被一个对象(tc)调用,
      2)除了没有名字外,看匿名内部类所在的位置,他的定义和访问将和成员内部类、静态内部类、局部内部类一样。
                 一般像局部内部类的定义和访问比较多。
      3)当试图创建接口或者抽象类对象的时候,用匿名内部类。
           表示类体的{...}紧跟在抽象实例(接口)之后,表示实现该抽象实例(接口)。
           调用匿名内部类的方法只能用写类时创建的那个对象(tc)。
作用:1,不破坏访问权限的情况下,内部类可以使用外部类的私有成员变量和方法。
           2,将接口公开,将实现类(实现公开的接口)作成内部类隐藏起来,强制要求使用者使用接口,强制降低偶合度。
           3,Java通过接口和内部类两种机制来实现多继承。在类内部可以建立本类的实例,然后调用本类内的其他方法。