OOP思想中,我们所认识的一切东西,都是对象(Object)
能够说出其特点并能与其他对象进行比较,而特点包括:
1. 对象的特征或者属性
2. 对象的行为
相信我们身边的一切,都是有相应的class与之对应
类(Class)是群体(或集合),而对象是类的一个个体,需要明白对象与类的关系。
类是一群具有共同重要特性的对象。类的定义即是说明这群对象有什么重要的特性(包括对象的特征及其行为),而软件中,对象以数据来表达特征,以函数来表达行为。
代码示例:
class People{
//特征描述(运用数据来描述)
private int age;
private String name;
//行为描述(方法描述)
public void say(){
System.out.println("My name is"+name);
}
}
//此时,new People()指令会产生一个People对象
//执行时候,会使用上面定义People的模型,去创建一个people实例
//这样,电脑内部就会有一个对象与自然界的People对应了
People people = new People();
//让该对象执行它的行为,那么电脑就会根据上面定义的行为描述去执行
people.say();
另外,实例(Instance):与对象含义相近似,而在计算机角度,实例偏向于,开辟了的存储空间。
继承(Inheritance):子类会继承父类的所有特性(特征以及其行为),也可以理解成子类是父类的扩展的一种形式。
对众多对象分门别类之后,可以形成一个继承体系。
可以这么看,Person是一个大的集合,而Teacher、Student因为自身拥有独特的特性(在满足人全部特性的前提下,老师需要教书这一行为,而学生需要做作业这一行为),所以它们是大集合中的一部分,也就是子集。
而定义子类时候,使用关键字“extends”,这翻译过来正是扩展的意思,也就是在父类的基础上再拓展自己独特的部分。
代码示例:
class Teacher extends Person{
//...
}
注意:继承的是父类的定义,而不是继承父类的定义项的具体数值。例如,父亲类年龄项,然后有个父亲对象年龄被设置成30,儿子类继承父亲类后,继承的是年龄项的这个定义,而与它后来被设置的具体数值是没有关联的。
//注意这种情况,如果父亲类定义时候已经设置了具体数值,那么,儿子类继承之后当然也就继承下来了
//因为,这个具有具体数值的定义项一并成为了父亲类的一个特征,所以儿子类当然也会具有这个特征
public class Father30{
public int age = 30;
}
public class Son extends Father30{
public void sayAge(){
System.out.println("年龄:"+age);
}
}
public class main {
public static void main(String[] args) {
Son son = new Son();
son.sayAge();
}
}
//输出:“年龄:30”
Android本身就提供许多完整的框架基类,而我们大多数情况下的开发,都基于框架上,继承相关类并做出相应的扩展,从而实现需求。
类与类的组合关系:接口(interface)与实现类的关系(implements),接口会定义一个等待实现的方法,实现类需要实现接口定义的方法,换一种说法,接口定义了一种格式,而实现类需要符合这种格式才能与接口对接(implements),就像电脑的USB接口,那么U盘就必须要有一个与这个接口相匹配的对接处才能接上电脑。
**例如:**Java中,提供了一个Thread基类和一个Runnable接口,那么这两个元素构成了一个框架。Thread基类有一个start方法,而Runnable接口有一个run方法。那么如何使用这个框架?Thread类需要传入一个Runnable接口的实现类,那么,就需要构造一个Runnable接口实现类。上述过程可以想像成,你需要打开U盘里面的一个文件(Thread.start();),首先你要接入U盘(传入一个Runnable接口实现类),而你需要这个U盘是一个能够符合USB规格的U盘才能接入(需要构造一个实现Runnable接口的实现类),而且你还需要保证U盘里面有你想要的文件(也就是根据需求,实现run方法)。
综上:这个框架工作原理就是,Thread基类先创建一个小线程,然后该线程通过Runnable接口,呼叫实现类实现后的run方法。
现在,换一种方式来思考,Thread类与Runnable接口,直接看的话,看似没有什么关系,但是通过理解上面的工作原理,那么就可以这么认为了:把Runnable塞入Thread中(就像把USB接口镶嵌在笔记本电脑上),然后Thread就看成一个抽象函数(不是真的是抽象函数,只是从结构上认为),而实现类的方法会覆盖掉Thread类中的run抽象方法,这样就变成了实现类是Thread类的子类了(注意,两者不是继承关系)。
那么,这样不就是基类子类的结构关系了吗?
也说明了组合关系可以变成这样一个基类子类的关系。
这样可以得出一个结论:
基类子类的结构可以呈现两种意义:
1. 继承关系
2. 组合关系
代码示例:
//此时extends的扩展的意思,而不是继承,而继承是扩充的一种
//因为run方法一定要覆盖掉才能在JMain中如此使用
class Task extends Thread{
public void run(){
//根据需求实现线程功能
}
}
public class JMain{
public static void main(String [] args){
Thread t = new Task();
//Task t = new Task(); 或者这么写
t.start();
}
}
工作原理,即基类子类工作原理:
new子类(Task)时候,会自动new基类(Thread)的对象,而run方法又被Task实现了,所以能如此使用