1.3.5 多态
三个层次
+ 生物上的多态:狗有很多品种,具有多态性
+ 面向对象理论中的多态:同一操作用于不同的类的实例,不同的类讲进行不同的解释,最后产生不同的结果
+ 编程角度:同样的程序语句,在不同的上下文环境中可能得到不同的运行结果
// example
Animal animal = new Dog(); // 不同上下文
animal.bite(); // 相同语句
Animal animal = new Dragon(); // 不同上下文
animal.bit(); // 相同语句
分类
继承多态
+ 基于抽象类/抽象方法1
+ 不能创建抽象基类的对象,只能用它定义变量来引用子类的对象
+ 抽象类 变量名 = new 继承自此抽象类的具体子类名();
+ 举个例子:饲养员喂养三种动物。如何解决?让三种动物继承动物基类,继承动物基类的吃的方法,然后把对不同动物对象的基类引用传给饲养员。
接口多态原理同上
1.3.6 对象的创建
new
对象注入
class B{}
class A{
privite B innerObj; // 使用一个私有变量保存B的引用
public A(B obj){ // 对象注入
innerObj = obj;
}
}
基于接口的对象注入(重要)
interface MyInterface{}
class B implement MyInterface{}
class A{
private MyInterface innerObj; // 利用接口访问B,相当于对B进行了一层抽象,可以断开A和B之间的强耦合性
public A(MyInterface obj){
innerObj = obj;
}
}
// usage
A obj = new A(new B());
基于抽象基类的注入同理
example 1
// object injection in Stream
FileInputStream fin = new FileInputStream(filename);
/*
* DataInputStream的构造函数
* public DataInputStream(InputStream in){
* super(in);
* }
* in fact
* FileInputStream extends InputStream(abstract)!
*/
DataInputStream din = new DataInputStream(fin);
Double s = din.readDouble();
example 2,单例模式,singleton
// 需求:限制new的次数
// 方案:将类的构造方法设置成私有,这时候外部无法使用new来创建对象;利用对象注入的思想,自己注入给自己
public class OnlyYou{
private static OnlyYou obj = null;
private OnlyYou(){}
public static OnlyYou getOnlyYou(){
if(obj == null){
obj = new OnlyYou();
}
return obj;
}
}
example 3,multi-thread
/*
* if(obj == null){...} 这里会出现同步的问题
* thread-1还没有实例化OnlyYou,thread-2进入判断,又会实例化一次OnlyYou,造成冲突
*/
// solution 1
... getOnlyYou(){
lock(typeof(OnlyYou)){ // 加锁,锁定整个类型
if(obj == null){
...
}
}
}
// solution 2, CLR
[MethodImpl(MethodImplOptions.Synchronized)] // 加锁,方法级别
... getOnlyYou(){
if(obj == null){
...
}
}
// 以上两个方法在不同级别上进行加锁,但是都不好
// solution 3 in C#,使用类的静态构造函数,在整个程序的声明周期只会被调用一次
class OnlyYou{
private OnlyYou(){}
private static OnlyYou obj = null;
static OnlyYou(){
obj = new OnlyYou();
}
public static OnlyYou getOnlyYou(){
return obj;
}
}
summary-1
这一篇和之前的两篇面向对象程序设计的文章中,最有实用价值的就是这一篇中的对象注入和单例模式,这两者对我们理解别人的程序、设计自己的程序都有很大帮助。待这一系列的课程结束之后,可以专门找某个语言的比如java的面向对象的书来仔细学习,有了基础那样就会很快。
- 包含抽象方法的类一定是抽象类,但是抽象类中不一定是抽象方法。 ↩