Java面向对象

  • Post author:
  • Post category:java




面向对象

  • 面向对象的三大特性: 封装、继承、多态




  • 从语法角度上看: 类是用class修饰符的
  • 类是抽象的,看不见也摸不着
  • 类是自然界用来描述具有相同的

    特征



    行为

    的事物的统称
  • 在编程中,特征用

    属性

    来表述, 行为用 方法 来描述



对象

  • 对象是类的具体实现, 万物皆为对象
  • 类是对象的模板



成员变量

在类中定义的变量

  • 使用方法:局部变量必须赋初始值才能使用,没有默认值
  • 作用范围:从生命开始 到离他最近的代码块结束



局部变量

在方法中定义的变量

  • 使用方法:有默认值,可以直接使用
  • 作用范围:在整个类中都可以使用

局部变量 和成员变量 的变量名可以一样,但局部变量会覆盖掉成员变量

如果 需要在方法中使用 被覆盖掉成员变量,那么可以通过 this 关键字来显式调用成员变量

this 代表 当前调用该方法的对象



构造方法

  • 作用
  1. 用来创建对象
  2. 给属性赋值 (一般通过有参构造方法)
  • 特点:
  1. 构造方法的方法名和类名完全一致
  2. 构造方法不用设置返回值类型
  3. 构造方法通过 new 来调用

当一个类中没有提供构造方法的时候,JVM会默认提供一个无参的构造方法

如果类中提供了构造方法,那么JVM就不会在提供默认的构造方法



方法的重载

在一个类中,方法名允许重名、这种一个类中多个相同的方法名 就被称为方法重载



方法重载的要求

  • 方法名相同
  • 参数列表不同 (参数的个数不同 或 参数的类型不同 (相同位的参数) )



实例代码块

  • 特点: 在类中定义的代码块
  • 作用: 在对象创建完成前、做一些初始化工作
  • 本质是 在构造方法 调用前执行的代码



权限修饰符

用来控制访问权限的

权限修饰符可以写在 类、 属性、方法、构造方法上

  • public (公共的)
  • protected (受保护的)
  • default/friendly (默认的、不写修饰符,就是默认的)
  • private (私有的)

类只能使用 public 或者 default 修饰

内部类 可以使用 所有权限修饰符

  • public : 可以在任意位置被访问和使用
  • protected : 修饰的方法、属性 只能在 子类 或者 同一个包 中 被使用
  • default : 只能在同一个包中被使用
  • private : 只能在自己的类中被使用



封装

将一个类中的属性 尽可能的私有化、并将方法进行公开



Field 和 Property

  • Field : 在类中定义的成员变量
  • Property : 在类中定义的 set/get方法,去掉 set/get 之后,首字母变小写

开发中一般要求 Field 和 Property 保持一致

ALT + 7 快捷键可以 打开 一个类的结构图



this 关键字

this 表示的 类对应的 对象, this 指的是 调用类中定义的 属性/方法 对应的那个对象

this 代表当前对象

  • this 可以调用成员变量
  • this 可以调用成员方法
  • this 可以调用构造方法 (构造方法调用类中的其他构造方法)

this 调用构造方法,需要后面跟

()

, 并且 this在调用构造方法的时候,必须出现在 构造方法的第一句



toString()

将对象 以字符串的形式来表示

toString 来自于 Object类、是所有对象都拥有的一个方法

打印一个对象、本质上是打印这个对象的toString()方法

public String toString() {
    ...
}



Object 类

在 java.lang 包中,是Java中所有类型(8种基本数据类型除外)的父类,表示对象

Object中定义的所有方法,所有类都可以直接调用



Object 中常见的方法

  • String toString() : 以字符串的形式表示一个对象

  • Class<?> getClass() : 获取一个对象的类型,一个对象有且只有一个类型

// 比较两个对象是否是同一个类型 
obj.getClass()  ==  obj2.getClass() ;
  • int hashCode() : 获取一个对象的 哈希值 、主要运用与 和 has 算法相关的操作中

  • boolean equals(Object obj) : 用来比较两个对象内容是否相等、但 Object中的 equals 默认比较的是 两个对象的地址

== 的作用 
1. 如果是两个基本数据类型做比较,那么 == 比较的是 两个值是否相等
2. 如果是两个对象做比较,那么 == 比较的是两个对象的地址是否相等 
3. 如果两个对象需要比较内容,那么只能用 equals 进行比较,但 但 Object中的 equals 默认比较的是 两个对象的地址,如果需要,自己需要重写 equals 
  • clone() : 可以克隆一个对象, 是一个受保护的方法

  • finalize() : 用来进行垃圾回收的方法,但在 JDK9已经被标记为过时



equals 方法的使用

官方定义的是 用来比较两个对象的内容是否相等,但 Object 默认比较的是两个对象的地址是否相等

Objects.equals(a, b) : 比较 a 和 b 的内容是否相等,可以解决 a , b 为空,空指针的问题

如果在 自定义的类中,比较两个对象的内容是否一致 ???

public boolean equals(Object obj) {
    if (this == obj) return true ; 
    if (obj == null || obj.getClass() != Dog.class) return false ;
    Dog dog = (Dog) obj ;
    // 追个比较属性
    return Objects.equals(type, dog.type) && Objects.equals(color , dog.color)
}



static 修饰符

static 可以修饰 属性、方法、代码块、 内部类



static 修饰属性

如果一个属性被 static 修饰,那么这个属性就被称为 静态属性

类中定义的属性是所有对象都拥有的特征、每一个对象的属性对应的属性值都是 相互独立的

静态属性的值被类的所有对象所共享、本质上和 对象 没有关系 ,静态属性只和类有关系

静态属性 推荐使用 类来进行调用,而不推荐使用对象调用



static 修饰方法

如果一个方法被 static 修饰,那么这个方法就被称为 静态方式

静态方法通过 类 来调用,不推荐 使用 对象 来调用

空指针异常: 如果一个对象的值是 null, 那么在调用成员方法的时候,就会发生 NullPointException(空指针异常)



static 修饰代码块



类加载

当 JVM

第一次

读取一个类的时候、会将 类的字节码信息 读取到 内存中,这个过程被称为 类加载

一个类 只会发生一次 类加载、 类加载的产物 被称为

类对象


一个类的类对象只有一个、用 Class 表示 , 获取 类对象的方式有三种



类对象的获取方式

  • 对象.getClass()
  • 类.class
  • Class.forName(“类的全名”)



类加载过程

  1. 分配空间
  2. 加载 静态属性 (此时属性还没有值)
  3. 从上到下,一次读取 静态属性 和 静态代码块
  4. 检查静态属性是否有值、如果没有值、则设置默认值
  5. 将静态方法加载到 方法区



final 修饰符

final 最终的意思

final 可以修改 类 、属性、 方法 、局部变量



final 修饰属性

  • final 修饰一个变量、那么变量就成为了 常量
  • 常量在 Java中,要求使用 全大写 的命名规范 、多个单词用下划线分割(蛇形标识)
  • final 修饰一个属性、那么属性的默认值就失效了, 要求 必须赋初值
  • final 修饰的属性,一旦赋值,不可更改
  • final 修饰的属性如果是 基本数据类型 ,那么代表 值不可改变
  • final 修饰的属性 如果是 引用数据类型, 那么代表 指向的地址不可改变
final 修饰属性 可以 赋值的 位置 

1.  在声明属性的时候,直接赋值 (常用)
2.  在代码块中 完成属性 赋值 
3.  在构造方法中,完成属性赋值 (常用)



final 修饰 局部变量

一个局部变量 可以被 final 修饰,且可以不需要给 初始值, 在使用前 赋初值 即可



final 修饰 类

如果一个类 被 final 修饰,那么 这个类 是一个最终类, 不能被继承

如果一个类 被 final 修饰,那么这个类中所有的方法 都会被 final 自动修饰



final 修饰 方法

如果一个 方法 被 final 修饰, 那么这个方法是一个最终方法, 不允许被 子类重写



枚举 Enum

使用 关键字 enum 来表示 ,

枚举中的每一个值 都表示 枚举类型对应的对象

枚举类可以定义私有构造方法、完成枚举值含义的介绍



继承



方法的重写

一定是发生在父子类中,且在子类中进行方法的重写

当父类中提供的方法不满足子类的需求的时候,才进行重写

能重写的方式 一定是 可以继承的方法

  1. 修饰符 和 父类 保持相同 或者 比 父类 修饰符的 权限 更宽
  2. 返回值、方法名、参数列表 三者必须和父类完全相同
  3. 异常的处理 必须和 父类 保持 相同 或者 比 父类更窄

可以使用 CTRL + O 快速重写父类的方法

@Override 注解 可以写在 被重写的方法上,用来做语法检查,如果不符合重写的要求,则代码会直接编译不通过



super 关键字

super 可以调用 父类的 属性、 方法、 构造方法



形参 VS 实参

形参: 在声明一个方法, 方法参数列表中定义的 参数名

实参: 在调用方法的时候,传入的参数被称为 实参

形参: 形参参数名 不是特别重要,只要符合标识符命名规范即可,重要的形参对应的数据类型

实参: 内容和类型都很重要



参数传递

  1. 引用传递 : 如果参数类型是 引用数据类型,发生 引用传递
  2. 值传递 : 如果参数是基本数据类型,发生 值传递

Java严格来说,没有引用传递,所有传递都是值传递



抽象类 和 普通类的区别

  1. 抽象类使用 abstract class修饰 , 而 类只使用 class 修饰
  2. 抽象类中可以有抽象方法、但类中不能出现 抽象方法
  3. 抽象类有构造方法但不能创建对象, 类有构造方法且可以创建对象
  4. 抽象类不能被final 修饰,而类可以



多态

将子类对象赋值给父类引用,调用父类的方法、显示子类的结果

缺点: 会丢失子类的特性

优势: 程序的可扩展性会更强

  • 向上转型: 将子类对象赋值给父类引用 (自动转换)
  • 向下转型: 将指向父类的对象 赋值给子类引用 (强制转换)



对象是不是某个类型

对象 instanceof 类型

if (obj instanceof Type) {
    
    Type type = (Type) obj ;
     
}

JDK16 新增特性

if (obj instanceof Type type) {
    ... ;
}



内部类

在 类的里面 或者 方法的方法 定义的类

  • 成员内部类

  • 静态内部类 (常用)

  • 局部内部类 (忘记吧)

  • 匿名内部类 (常用)



成员内部类

在类中定义的成员类

public class Bank {

    public  class ATM {
    
    }
}

// 创建 ATM 对象
Bank.ATM atm = new Bank().new ATM(); 



静态内部类

在类中定义的 静态类

public class Bank {

    public static class ATM {
    
    }
}

// 创建 ATM 对象
Bank.ATM atm = new Bank.ATM(); 



局部内部类

在方法中定义的类

public  class Bank {

    public int getMoney(int money) {
    
        class ATM {
            public getMoney(int money) {
                return money ;
            }
        }
        
        return new ATM().getMoney(money);
    }
}



匿名内部类

  • 本质: 快速的构建一个类的子类(匿名类)对象
// 快速创建一个 Dog 的子类对象
Dog dog = new Dog() { ... }



版权声明:本文为weixin_44703268原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。