# 面向对象

你是上帝,创造对象,让对象干活。

优点:减少代码量、可扩展性强、维护成本低
缺点:上帝视角、上手难度相对大

#

设计方案:属性(class 里的变量,即成员变量) + 动作(public 不加 static,即成员方法)

# 对象

类的实例。

创建方法new

// 类 引用 = new 类 ();
car c = new car();

# this 关键字

当前正在执行这个方法的对象。

  • 在调用方法的时候,Java 会自动地把对象传递给方法,在方法中由 this 来接收对象。
  • 不加 this 的变量的查找顺序:自己方法内找(局部变量)> this 里面找(成员变量)。
  • this 还可以调用当前类中的其他构造方法(通过 this(参数) ,而不是 this.xxxx )。

# 构造方法

  • 没有返回值。
  • 在执行 new 的时候自动调用构造方法。
public 类名(参数){
}

# 构造方法重载

  • 构造方法也是方法,也可以进行重载。
  • 方法名称相同,参数个数不同。
  • 从而可以有更多的方式创建对象。

# static

  • 静态的内容在内存中只保留一份。
  • 其内容由各个对象共享。
  • 推荐使用类名访问静态内容。

# 通用构造器 & 静态构造器

(都不常用)

创建对象的过程:先执行静态构造器,再执行通用构造器,最后执行构造方法。因此,在静态方法里不能使用 this ,因为 this 还没生成。

public class test{
  {
    System.out.println("这里是通用构造器");
  }
  static {
    System.out.println("这里是静态构造器");
  }
}

#

  • 所有程序都平铺在 src 里不好维护。
  • 包名一般用公司域名的翻转 (如 com.baidu.tieba )。
package com.baidu.tieba;

# 导包

  • 不需要导包:

    • 在自己包里不需要导包;
    • java.lang 包下的所有内容不需要导包。
  • 导包格式:

import com.baidu.tieba.person;
import com.baidu.tieba.*;

# 访问权限

  • public 公共的,所有人可访问(常用)。
  • default 包访问权限,自己包内可以随意访问。
  • private 私有的(常用)。

# setter

  • private 成员变量赋值,可以添加保护。
  • IDEA 可以右键 generate -> getter and setter 自动生成。

# getter

  • private 成员变量获取数据。
  • IDEA 可以右键 generate -> getter and setter 自动生成。

# 继承

子类可以自动拥有父类中除了私有内容外的其他所有内容。

作用:简化代码的开发。

当出现 x 是一种 y 的时候,x 就可以继承 y(黑熊怪是一种妖怪)。

public class HeiXiongGuai extends YaoGuai{
}

# super 关键字

  • this 先找自己类再找父类, super 表示父类中的内容。
  • 可以用 superthis 来区分父类和子类中重名的内容。
  • 可以用 super() 来调用父类构造方法,需要写在子类构造方法的第一行。
  • 如果父类构造方法不包含参数,可以不写;如果包含参数,一定要写。
  • 在调用子类构造方法时,会在进入子类构造方法时调用父类构造方法,再回到子类的构造方法。
public class zilei extends fulei{
  public zilei(){
    super();// 即使不加这行代码,这里也会默认调用 super ()
    System.out.println("我是子类构造方法");
  }
}

# 方法的重写

子类对父类中提供的方法进行重新定义。

语法:子类和父类中的方法的声明完全一致。

# 多态

同一个对象拥有多种形态。

作用:把不同的数据类型进行统一,但真正执行的时候依然会按照每个数据类型进行执行。

  • 向上转型:把子类的对象赋值给父类的引用 (会屏蔽掉子类中特有的方法,因此还需要向下转型)。
  • 向下转型:把父类的变量转换回子类的变量(向下转型有风险,需要写强制类型转换)。
// 向上转型
animal ani1 = new cat();
animal ani2 = new dog();
// 向下转型
cat cc = (cat)ani1;
ani1.eat();        // 可执行
ani1.CatchMouse(); // 不可执行
cc.CatchMouse();   // 可执行

# final

  • final 修饰的变量不可被改变,又被称为常量。
  • final 修饰的方法不可被重写。
  • final 修饰的类不可被继承,即不能产生子类。

# 抽象

只声明,不实现。

  • abstract 修饰方法,直接用分号结束。
  • 如果一个类中有抽象方法,那么这个类一定是一个抽象类。
  • 抽象类不可以造对象,即不可以 new
  • 抽象类的子类必须重写抽象类中的抽象方法(通过抽象类可以强制要求子类中有哪些方法)。
  • 抽象类中可以有正常的方法。
public abstract class animal{
  public abstract void eat();
  public void smell(){
    // ……
  }
}

# 接口

接口实际上是一种特殊的抽象类,其中所有的方法都是抽象方法。

  • 使用 interface 声明。
  • 能继承接口的只能是接口。
  • 接口和类只能是实现关系。
  • 接口同样具有多态性。
  • 方法可以省略 abstract
  • 接口中所有方法默认都是 public 的,所有变量都是全局静态最终常量。
  • 类只能单继承,而接口支持多实现。

作用:接口可以把很多不相关的东西进行整合。

public interface valuable{
  public abstract void getMoney();// 接口中所有的方法都是抽象方法
}
public class Gold implements valuable{
  // 必须要重写抽象方法
  public void getMoney(){
    System.out.println("类实现接口,重写抽象方法");
  }
}
public class Panda extends animal implements valuable, protectable{
  // 类可以继承一个类,实现多个接口
}
public static void main(){
  // 接口同样具有多态性
  panda p = new Panda();
  animal ani = new Panda();
  valuable v = new Panda();
  protectable p = new Panda();
}

# 成员变量的初始值

  • java 中所有的变量必须先声明再赋值才可使用
  • java 中的成员变量在创建对象的时候都会执行一次初始化操作,给一个默认值:
    • byte:0
    • short:0
    • int:0
    • long:0
    • float:0.0
    • double:0.0
    • char:0
    • boolean:false
    • string (string 是 java 提供的一个类):null
    • child (自己写的类):null
  • 即基本数据类型默认都是 0,包括 boolean;引用数据类型都是 null

# object

所有的东西都是对象

  • object 是一个类,是所有类的根
  • 在 java 中,所有的类都要继承 object;我们写的类,即使不写继承关系,默认也会继承 object
  • equals(object 提供的方法):用来判断两个对象是否相等
    • equals==
    • == 一般用于基本数据类型,不用于对象
    • equals 默认用法与 '==' 相同,但可以通过重写添加自己的判断逻辑
    • equals 用法:
System.out.println(c1.equals(c2));
  • 字符串的判断一定要用 equals:
String str1 = "lessone";
String str2 = "lessone";
// 重用了同一块内存
System.out.println(str1==str2);         //true 地址相同
System.out.println(str1.equals(str2));  //true 内容相同
String str3 = new String("111");
String str4 = new String("111");
System.out.println(str1==str2);         //false 判断的是地址,地址不同
System.out.println(str1.equals(str2));  //true String 中重写了 equals,用于判断内容是否相同
  • toString(object 提供的方法):对一个对象字符串的表示形式,JAVA 官方推荐重写这个方法
    • 直接打印对象会默认执行 toString 方法
    • 默认的 toString 返回:包名 + 类名 @内存地址

# instanceof

  • instanceof 关键字:判断 xxx 对象是否是 xxx 类型的
  • 用法:
if(ani instanceof cat){
  // ...
}

# 参数传递

参数传递包括值传递和引用传递,java 使用的是值传递

# 值传递

把变量的值作为参数传递

public class Test {
  public static void change(int b){
    b = 20;
  }
  public static void main(){
    int a = 10;
    change(a);
    System.out.println(a);  // 结果为 10
  }
}

把变量作为参数传递

public class Test {
  public static void change2(Cat c){
    c = new Cat("NewName"); // 创建一个新的猫,change.c 指向新猫的地址,外面的 c 仍指向原来的猫的地址
    // 运行完后 change.c 被回收,新猫被回收
  }
  public static void main(){
    Cat c = new Cat("OriginalName");
    change2(c); // 传入 c 的值,即原来的猫的地址
    System.out.println(c.name); // OriginalName
  }
}
public class Test {
  public static void change3(Cat c){
    c.name = "NewNewName";  //c 为原来猫的地址,故修改成功
  }
  public static void main(){
    Cat c = new Cat("OriginalName");
    change3(c); // 传入 c 的值,即原来的猫的地址
    System.out.println(c.name); //NewNewName
  }
}
更新于