Java速通2:面向对象

143 阅读5分钟

1.包:

  1. 如果公司域名中有非法字符,建议使用下划线(_)来使包名合法化。
  2. java编译器为每个源文件自动导入2个包
    • import java.lang.*;
    • import 当前文件所在包.*; 这样同一包下的类,互相使用,就不用导包了
  3. 静态导入:
    • 可以省略类名来访问静态成员(成员变量、方法、嵌套类)

    • 正确使用静态导入,可以消除重复类名,提高代码可读性。

    • 过度使用静态导入,读者会分不清静态成员是哪个类中的。(所以不建议使用静态导入)

      // 静态导入举例
      import static java.lang.Math.PI;
      
      // 使用(PI可以直接使用)
      System.out.println(2 * PI);
      

2.构造方法:Constructor

  1. 构造方法无返回值
  2. 如果一个类未定义构造方法,编译器会为其提供一个默认的无参构造方法。
  3. 一旦定义了构造方法,默认无参构造方法将不存在。
  4. 构造方法有个默认参数this:如Peron的无参构造方法,实际样子->public Persion(Persion this){}

3.this:是一个指向当前对象的引用

  1. 可访问当前类中定义的成员变量
  2. 调用当前类中定义的方法(包括构造方法)

4.继承:

  1. java.lang.Object 是所有类的父类(新建一个类,它默认继承Object类)
  2. 子类可以定义与父类重名的成员变量(不建议这么做)
  3. 重写:子类的方法签名和父类一样。也叫覆盖
  4. super:代表父类
  5. 子类重写的方法权限必须 ≥ 父类的方法权限
  6. 子类重写的方法返回值类型必须 ≤ 父类的方法返回值类型

关于this 与 super

//只有在构造方法里面,才能用super/this来调用构造方法
public class Persion{
    public String name;
    public int age;
    
    public Persion(){
        
    }
}

public class Student extends Persion{
    
    public String name;
    public int age;
    
    public Student(String name, int age){  
        this.name = name;
        this.age = age;
        super.age = age;
    }
    
    public Student(String name){
        this(name, 0); //使用this  调用构造方法
        super();        //使用super 调用父类构造方法
    }
}

1、子类的构造方法必须先调用父类的构造方法,再执行后面的代码。
即子类构造方法的第一句默认为 super(); 目的是让父类比子类先初始化。
如果显式的调用 super(), 默认的就无效了。
所以上面例子会报错,因该改为:

public Student(String name){
    super();        //使用super 调用父类构造方法
    this(name, 0);  //使用this  调用构造方法
}

2、上面改后依然报错,提示 this(name, 0) 必须放在第一行。
因为有参构造方法里面也有 super() 这里第一行也是 super()
导致父类被加载两次,重复了。删除super()即可。

public Student(String name){
    this(name, 0);
}

关于继承 父类变量私有化:

// 问:子类对象的内存中,是否包含父类中定义的private成员变量
public class Persion{
    private String name;
    //提供getter和setter方法
}

public class Student extends Persion{
    public int age;
}

Student st = new Student();
st.name; //报错
st.getName(); //证明name变量存到了student对象中了。
//private只是做访问控制,让外界不能直接访问name,但不代表name就不存在了。

5.访问权限:

public:在任何地方都可见 protected:仅在本包中,自己子类中可见 default(无修饰符):仅在本包中可见 (所以无修饰符又叫包私有权限) private:仅在自己类中可见

1.上述4个访问权限都可以修饰类的成员,比如成员变量、成员方法、嵌套类等(即类中的一切)
2.只有publicdefault可以修饰顶级类。(顶级类定义出来就是被使用的,定义成其他类型就无法被使用,失去了存在的意义)
3.以上4个访问权限不可修饰局部类,局部变量。(局部变量的作用域仅限在方法里,与访问权限的意义相矛盾)

//一个java文件中,最外面的那个类叫顶级类
public class Persion{
    //嵌套类
    class ABC{
        class Test{
            
        }
    }
    
    public void test(){
        // 修饰局部变量no
        private int no = 10; //会报错
    }
}

6.封装:

1、成员变量private化,提供public的getter、getter方法。
toString(): println(对象引用),当参数为对象引用时,println会调用对象的toString方法

7.多态:

  1. 什么是多态?
    • 具有多种形态
    • 同一操作 作用于不同对象,产生不同的结果
  2. 多态的体现:
    • 父类(接口)类型引用 指向 子类对象
    • 调用子类重写的方法
  3. JVM会根据引用变量指向的具体对象来调用对应的方法。
    • 这个行为叫:虚方法调用(Virtual method invocation)
    • 类似于C++中的虚函数调用

8.static:

  1. 常用来修饰类的成员:成员变量,成员方法,嵌套类
  2. 被static修饰的变量:类变量,静态变量,静态字段。(放在方法区,只有一份内存)
  3. 未被static修饰的变量:每一个对象实例,都会有此变量,所以叫实例变量(每个对象内部都有一份内存)
  4. 被static修饰的方法:类方法,静态方法。(内部不可以使用this,因为被static修饰的东西先加载。加载后发现找不到当前对象,会报错。)
  5. 静态代码块:
    • 当一个类被初始化的时候,执行静态代码块。
    • 当一个类第一次被主动引用的时候,JVM会对类进行初始化。
    • 静态代码块在整个程序运行期间,只执行一次。
    • 静态代码块常用来做类内部的一些初始化。

静态变量应用:比如统计创建了多少个对象

public class Persion{
    public static int count;
    
    static {
        count = 0;  //也可在静态代码块中为静态变量赋值()
    }
    
    public Persion(){
        count++;
    }
}