在Java中面向对象是通过类的形式来体现的。
这篇介绍属性、权限修饰符、方法修饰符、代码块等。

类:事物的描述。(包含属性和行为)
对象:该类事物的实例 在java中通过new来创建的

面向对象 - 图1

  • 描述类,其实就是在定义类中的成员(成员变量 [属性] 和成员函数[行为]
  • 第一个Car表示变量类型,声明 c 就是用一个类类型的引用变量,指向了该类的实例。


属性 vs 局部变量

image.png

相同点:

  1. 定义变量的格式:数据类型 变量名 = 变量值
  2. 先声明,后使用
  3. 变量都其对应的作用域

不同点:

在类中声明的位置的不同:
属性:直接定义在类的一对{ }内
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量

关于权限修饰符的不同:
属性:可以在声明属性时,指明其权限,使用权限修饰符。(private、public、缺省、protected)
局部变量:不可以使用权限修饰符。

默认初始化值的情况:
属性:类的属性,根据其类型,都默认初始化值。
引用数据类型:如类、数组、接口,初始值为null
局部变量:没默认初始化值。

在内存中加载的位置:
属性:加载到堆空间中 (非static修饰,被static修饰就变成在方法区中了)
局部变量:加载到栈空间


权限修饰符

权限修饰符分为:private、public、缺省、protected四种。
image.png

4种权限都可以用来修饰类的内部结构,即:属性、方法、构造器、内部类
修饰类的话,只能使用:缺省、public(内部类除外)

private修饰符

面向对象 - 图4

  • 在成员属性之前 + private(使该类只仅在本类中有效)
  • 限制该成员属性只能在定义它的类中进行修改、赋值、访问
  • 其他类想要访问到这个属性,只能通过方法,或者反射



    面向对象 - 图5

  • 将成员属性私有化,再定义一个接口提供给用户,这就是封装性

  • 同时,这个接口里面还可以对成员属性进行控制(if判断)
  • set方法一般返回类型是void,get方法返回类型跟传入的参数相同。


public修饰符

被public所修饰的成员可以在任何类中都能被访问到。. public能用来修饰类,在一个java源文件中只能有一个类被声明为public,而且一旦有一个类为public,那这个java源文件的文件名就必须要和这个被public所修饰的类的类名相同,否则编译不能通过。

default(默认)修饰符

即在成员的前面不写任何的访问修饰符的时候,默认就是友好的。所谓友好的,是对同一package的类友好。
同一package中的所有类都能访问。被default所修饰的成员只能被该类所在同一个package中的子类所继承下来。

protected修饰符


protected作用于继承关系。定义为protected的字段和方法只可以被其子类同个包下的子类访问,以及子类的子类,而其他类无法访问。


案例一:不同包,不可使用
面向对象 - 图6

案例二:相同包,没有继承,可以使用
面向对象 - 图7



方法修饰符

方法修饰符分为:static、final、abstract三种。

static关键字

面向对象 - 图8

  • static也可以认定为修饰符,修饰于成员属性之前,称为对象的共享数据
  • 可以通过类名直接访问被static修饰的成员
  • 静态成员/静态方法优先于对象而存在(因此方法内不存在this、super关键字),伴随类的加载而加载,伴随所在类的销毁而销毁
  • 存放在内存中的方法区(静态方法区)

注意事项说明:

  1. 静态方法只能访问静态成员:因为静态方法的加载优先于静态成员,所以没有办法访问到实例属性(还没完成实例化,一切跟对象相关的操作都不能出现)
  1. 主函数为什么是静态的?这句话是围绕着“静态方法只能访问静态成员”这句话来讲的,在main函数中,你要是想访问非静态的成员或方法的话,就需要通过一个对象、类去调用,或者改变非静态为静态


Final 关键字


final翻译为最终

  • 被final修饰的方法就是最终方法,不可以被子类覆盖(比如:Object类中getClass();)
  • 被final修饰的类就是最终类,不能被子类继承(比如String类、System类、StringBuffer类)
  • 被final修饰的变量一般都是常量,一旦被定下,就不允许被修改


    被final修饰的类,其内部方法都会被赋予final,而静态域则不会。

abstract关键字

抽象类

  • 此类不能实例化。为什么?因为调用抽象方法没意义。
  • 抽象类中一定有构造器,便于子类实例化时调用
  • 开发中,都会提供抽象类的子类,让子类对象实例化,完成具体的操作 —->抽象的使用前提:继承性(抽象类必须有其子类覆盖了所有的抽象方法后,该子类才可以实例化。)

抽象方法

  • 抽象方法只方法的声明,没方法体
  • 抽象方法必须定义在抽象类中。该类必须也被abstract修饰。
  • 若子类重写了父类中的所的抽象方法后,此子类方可实例化
  • 若子类没重写父类中的所的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰

抽象类的匿名子类对象

image.png

  • Person是个抽象父类,按抽象类的定义来说,是没办法直接new对象的
  • 但是这里又内部实现了抽象方法,可以理解为是一个匿名子类


代码块

静态代码块

就是使用static关键字标识的代码块
其随着类的创建而运行,优先于非静态的方法、非静态的代码块

构造代码块

没有标识符,就是一个类中用{}包裹的代码,随着对象的实例化而运行
可以给所有对象进行实例化

跟构造函数是不同的概念:

  • 构造函数是根据特定对象进行实例化的(多个构造器)
  • 构造代码块是一创建就实例化。


已使用 Microsoft OneNote 2013 创建。