面向对象 (上)

类和对象

类和对象都是 数据和行为封装起来后产生的实体 ,是java中的基本单位

类是对象的模板/模板,对象是类的实例

类的组成部分

成员变量 方法 构造器 初始化块 内部类

对象的产生 对象变量名 与引用

this的使用

对象的创建

创建对象的过程
java大体上会把内存分为四块区域:堆,栈,静态区,常量区。

堆 : 位于RAM中,用于存放所有的java对象。
栈 : 位于RAM中,引用就存在于栈中。
静态区 : 位于RAM中,被static修饰符修饰的变量会被放在这里
常量区 :位于ROM中, 很明显,放常量的。

方法

方法的参数传递—值传递

方法重载(overload) 两同一不同

重载方法的优先级:
a.先匹配参数个数
b.参数类型的最佳匹配:直接所属类
c.如果没有找到直接所属类,会发生向上转型,直至找父类参数,直观上查找顺序为:包装类-》父类-》接口(不一定准确,《深入理解Java虚拟机》有更详细的描述)
d.如果向上转型仍无法匹配,则查找可变参数列表
e.以上无法匹配返回找不到方法错误。

构造器

无构造器时默认提供 无参构造器,有任何一个构造器则不再默认提供无参构造器

构造器overload 与this的使用

成员变量与局部变量

初始化

覆盖与this的使用

初始化

成员初始化块 用来初始化对象

成员变量声明时附 初始值 也可以理解 是一个初始化块

顺序根据代码顺序 但初始化块总是在构造器前执行 (注意:继承 ,同样最先执行顶级父类的初始化块,再执行顶级父类的构造器 以此类推 最后执行 本类)

静态初始化块 用来初始化类的静态成员 在类初始化时执行 同样先执行顶级父类的 静态 初始化块等等

封装

package、import

访问控制符(外部类访问控制符 、类内部成员访问控制符)

包 也是一个很重要的层面 比如 包内 继承 比较安全,但是跨包 继承 则会比较危险 跨包继承的类必须是专门为了继承而设计,且有文档说明 哪些方法被修改后 会影响到什么方法

封装 跟版本发行 包 private都有关系

继承

子类扩展(extends)了父类 父类派生(derive)了子类

继承破坏了封装

子类拥有父类非 private 的属性、方法 除此之外都不拥有

里氏替换原则 --父类能够出现的地方,子类也能够出现

单继承、直接父类、间接父类

方法重写override (三同两小一大)与super

子类不会继承父类的private方法,如果子类是否 有和父类相同的private方法签名 则都不是重写或者重载

子类不会继承父类构造器 如果父类 没有无参构造器,则子类必须在构造器第一行显示调用父类有参构造器

子类构造器必然调用一次父类构造器 且先执行最高类层次的构造器,最后才是本类的构造器

多态

编译时类型 和运行时类型不同

向上转型 继承链中对象方法的调用的优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

向下转型 向下转型前必须先向上转型

多态存在的三个必要条件:1)要有继承;2)要有重写;3)父类引用指向子类对象

多态 通过动态绑定(dynamic binding)技术来实现

instanceof运算符 变量 instanceof Class 前面的变量的 运行时类型 是后面的类或者子类 或者实习类的实例

如果变量编译时类型 引用指向的类和Class没有继承关系 或者 不是其本身 ,则报异常

类间的关系

uml类图中:类之间的关系大体上存在三种—泛化(继承或者实现)、依赖、关联(包含 聚合、组合)

关联 是一个类能访问另一个类 组合则比聚合更严格

组合 a实体 只能组成b实体,而不能再去组成另一个实体 即b实体生命周期结束 ,则a实体的生命周期也结束

但在 oo一般概念中 组合(composition)通常包含了uml 中的 聚合

依赖和 组合/聚合的区别是 A依赖 B只是 使用B类实例作为参数,或者调用B类对象的方法或者B类的静态方法,而非将B类 实例 作为成员变量

习题

问最后输出结果?


public class Father {
	public Collection doSomething(HashMap map){
		System.out.println("父类被执行...");
		return map.values();
	}
}
public class Son extends Father {
//放大输入参数类型
	public Collection doSomething(Map map){
		System.out.println("子类被执行...");
		return map.values();
	}
}

//这个类非常简单,就是把HashMap转换为Collection集合类型,然后再定义一个子类,源


public class Client {
	public static void invoker(){
		//父类存在的地方,子类就应该能够存在
		Father f = new Father();
		HashMap map = new HashMap();
		f.doSomething(map);
	}
	public static void main(String[] args) {
	invoker();
	}
}

代码运行后的结果如下所示:
父类被执行…

猜你喜欢

转载自blog.csdn.net/qq_19934363/article/details/86561977