面向对象基础
对象
现实世界的抽象,由两大特性组成:
- 状态
- 行为
优点:
- 模块性
- 信息隐藏,外部不会看到实现细节
- 代码重用
- 插件与调试,如果一个对象代码出问题了,可以被替换
创建对象通常包含三阶段(如Point p = new Point(1,2);
):
- 定义(
Point p
) - 实例化(
new
) - 初始化(调用构造器
Point(1,2)
)
一个对象可以有多个引用指向它
实例化的几种方式
- new
- 反射,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法
- clone()方法
- 反序列化方法,调用java.io.ObjectInputStream对象的readObject()方法
其中,方法3不会调用对象的构造方法,方法4内部实现似乎没有用到本地方法,也是调用newInstance()来构造对象的好像
类
可以看作用来创建对象的蓝图或原型
一般类的定义可包含以下(有序)内容:
- 修饰符(像public,private)
- 类名(约定上第一个字母大写)
- 继承(使用关键词extends)
- 实现的接口(使用关键词implements)
- 类主体(用大括号{}包围)
内部类
分为:
- 静态内部类(static nested classes)
- 非静态内部类(inner classes)
为什么使用内部类?
- 只在一个地方使用的类的逻辑组织方式
- 增强封装性
- 更好的阅读性与维护性代码
实例化静态内部类: OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
非静态内部类的实例只能在外部类的实例内,即如果要初始化非静态内部类,则必须先初始化外部类: OuterClass.InnerClass innerObject = outerObject.new InnerClass();
非静态内部类不能有静态成员,除非编译期可以评估为常量如public final String a = "xxx"
,但public final String a = new String("xxx");
不行
内部类不推荐序列化,因为是由编译器合成的构造内容(实现java功能特性而不用修改JVM),不同的编译器可能生成不同的内容,因此在不同的运行环境下可能产生兼容性问题.
局部内部类: 指在任意代码块内的内部类
匿名内部类: 没有名字的内部类,当只需要使用一次时使用
局部内部类与匿名内部类访问的局部变量必须是final的,JAVA1.8版本增加了Effictively final,即如果变量赋值后值不变,则认为是final的,可以不加final修饰符
方法
一般方法的定义可包含以下(有序)内容:
- 访问修饰符
- 返回类型
- 方法名
- 参数
- 异常
- 方法体
方法签名
: 由方法名
与参数类型
组成,同一个类内的方法签名
不能相同(但方法名可以相同),如run(int, double)
方法重载: 指方法名相同但方法签名
不同
covariant return type: 父类中某个方法可以在子类中override,并且返回值是父类那个方法返回值的子类.但父类中的静态方法无法被子类覆盖
方法什么时候返回?
- 方法内语句运行结束
- 遇到return语句
- 抛出异常
构造方法
类似方法,但方法名使用类名,且无返回类型.
如果未定义构造方法,则编译器会提供默认无参构造方法.
继承
允许从其它类继承共通的属性,并且有自己额外的功能
接口
类与现实世界的连接,如果类实现了接口,则必须实现接口内的方法
JDK规定了接口是static final
的(指接口本身而非其内的成员)(因此接口只能定义在静态上下文中)
包
用来组合相关的类与接口的命名空间
this
-
用来引用成员变量
public class Point { public int x = 0; public int y = 0; //constructor public Point(int x, int y) { this.x = x; this.y = y; } }
-
调用其它构造器(必须放在构造器内的第一行)
public class Rectangle { private int x, y; private int width, height; public Rectangle() { this(0, 0, 1, 1); } public Rectangle(int width, int height) { this(0, 0, width, height); } public Rectangle(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } ... }
访问指定范围:
public class A {
private int x = 1;
public class B {
private int x = 2;
public void test(int x) {
//2
System.out.println(this.x);
//1
System.out.println(A.this.x);
}
}
}
访问控制
- 类级
- public
- 默认(包私有)
- 成员级(包括内部类)
- public
- protected
- 默认(包私有)
- private
访问符 | 类 | 包 | 子类 | 公共 |
---|---|---|---|---|
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
默认(包私有) | Y | Y | N | N |
private | Y | N | N | N |