面向对象编程
大纲:
-
OOP的基本概念是对象,类,属性方法接口和枚举
-
独特功能:封装与信息隐藏;继承和重写;多态、子类型和重载;静态与动态分配。
-
一些重要的方法
-
如何设计好的类
文章目录
一些基本概念
类成员变量,类方法都是与类相关联的,而不是与类的实例相关联的(这些叫做实例方法和实例成员变量),也就是通过static修饰。
Java接口的用处是通过实现接口的类。接口就是一个方法列表,但是没有方法体,接口中没有构造器。 实现接口的类需要提供接口的所有方法体,接口可以继承多个其他的。如果有相同的方法怎么办?(查阅相关资料,如果接口中具有相同名字的方法,需要利用显示实现的方式,如下程序)一个类可以实现多个接口,一个接口可以有多个实现类。
class Program{
static void Main(string[] args){
SimpleOutput s = new SimpleOutput();
IOutput io = s;
ILog il = s;
s.output();
io.output();
il.output();
Console.ReadLine();
}
}
interface IOutput{
void output();
}
interface ILog{
void output();
}
class SimpleOutput : IOutput, ILog{
public void output(){
Console.WriteLine("SimpleOutput .....");
}
void IOutput.output(){
Console.WriteLine("IOutput...");
}
void ILog.output(){
Console.WriteLine("ILog...");
}
}
接口确定ADT规约,类实现ADT;也可以直接使用类作为ADT;实际中更倾向于使用接口来定义变量。Set其实是一个interface
,但是使用set来定义变量。
作用:
- 接口 以及 工厂模式以及IOC模式的运用, 可以很好的减少模块之间的耦合,便于以后系统引用实例的更改! 我觉得这是接口的最大功用!(假如一个类实现了多个接口,那么用接口类型来定义它的引用变量的话,一眼就可以明白,这里是需要这个类的哪些个方法;用接口类型定义引用变量,以后需要修改其引用的实例时,改动的地方要少一些!)
- 接口和抽象类都是对类的抽象,对类的划分,是最高层的抽象!
三个错误图中说明很清楚了,首先需要和接口的不变性相同,要包含接口中所有的方法,还有就是一个表示独立性的问题,不是很懂?
使用接口声明一个对象时,由于接口中没有构造方法,只能调用实现类中的相同名字的构造器,但是不能保证所有的实现类中都包含,所以需要知道该接口中某个具体实现类的名字。注意:可以使用静态工厂方法取代构造器。Java8允许接口包含静态方法。default方法在接口中统一实现某些功能,无需在各类中重复实现它。这种方法以增量式的为接口增加额外的功能而不去破坏以实现的类。可重写吗?
Inheritance and Overriding
严格继承:子类只能添加新方法,无法重写超类中的方法。严格继承是针对方法的。如果一个方法不能被重写,则它应该被final修饰。
如果我希望一个方法需要重写,我会将方法体置为空。
利用super和this来调用父类或者本类的方法。
抽象方法和抽象类需要用abstract
修饰,具有一个抽象方法就被称为抽象类;接口就是一个只有抽象方法的抽象类。
protected
元素在子类中是可见的
Polymorphism, subtyping and overloading
多态有三种,分别是特殊多态,参数化多态和子类型多态。
特殊多态
特殊多态可以使用不同的参数和返回值,重载可以使用不同参数、相同名字的方法,方便用户端调用。重载是静态多态,根据参数列表进行最佳匹配,在调用时(编译阶段)进行静态检查。重写方法在运行阶段进行动态检查。
重载必须使用不同的参数,可以不同的返回值,可以不同的范围,可以不同的异常,可以在本类重载也可以在子类重载。
Animal animalRefToHorse = new Horse();
第三这个,b的类型是Animal,所以它具有的属性和方法必须是类Animal中具有的,但是它指向的对象是Cow,所以调用方法时调用的是Cow中的方法。
参数多态和泛型编程
如果一个函数在多种类型中都类似地?工作,那么这个函数具有参数多态性。它根据运行时给的参数进行工作。java的集合 Set< E >.
实现泛型接口有两种方式:泛型接口,非泛型的实现类,交给具体的类给定对象去实现接口抽象方法;泛型接口,泛型的实现类,直接在接口实现,不需要选择E的类型,例如hashset和set。
< ?>通配符,在使用泛型时出现。
运行时泛型就消失了。
不能创建泛型的数组。
子类型多态
Java类能实现多个接口,只能继承一个父类。
B是A子类型意思是每一个B都是A,也就是继承的意思嘛。同时,每一个B都满足A的规约,子类型不能弱化父类型的规约。
子类型多态:不同类型的对象可以统一的处理而无需区分,从而隔离了“变化”。
instanceof
用于测试是否属于给定的类,但是避免在父类中检查子类的类型。
强制类型转换的前提是父类引用指向的对象的类型是子类的时候,ClassCastException
是类型转换异常。避免向子类型强制转换。
一些重要的方法
equals();
hashCode();
toString();
如何设计好的类
**不可变类优点:**简单;Inherently Thread-Safe 固有线程安全性;可以自由的共享;不需要防御性拷贝;Excellent building blocks。
什么是线程安全性
《Java Concurrency In Practice》一书的作者 Brian Goetz 是这样描述“线程安全”的:“当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的”。
在这定义中,最核心的概念是“正确性”。
在计算机世界中,在一段程序工作进行期间,会被不停的中断和切换,对象的属性(数据)可能会在中断期间被修改和变脏。
在 Java 语言中,线程安全性的问题限定于多个线程之间存在共享数据访问这个前提,因为如果一段代码根本不会与其他线程共享数据,那么从线程安全的角度来看,程序是串行执行还是多线程执行对它来说都是完全没有区别的。
如果每个线程中对共享数据(如全局变量、静态变量)只有读操作,而无写操作,一般来说这种共享数据是线程安全的,而如果存在多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。