什么是面向对象?什么是面向过程?
面向对象一般和面向过程结合来看的
面向过程(Procedure Oriented 简称 PO):把事情拆分成几个步骤(相当于拆分成一个个的方法和数据),然后按照一定的顺序执行。
面向对象(Object Oriented 简称 OO):面向对象会把事物抽象成对象的概念,先抽象出对象,然后给对象赋一些属性和方法,然后让每个对象去执行自己的方法。
举例:用洗衣机洗衣服,来看一下两者的差别。
面向过程:
放衣服(方法)—>加洗衣粉(方法)—> 加水(方法)—> 漂洗(方法)—> 清洗(方法)—> 甩干(方法)
面向对象:
new 出两个对象 ”人“ 和 ”洗衣机“
”人“ 加入属性和方法:放衣服(方法)、加洗衣粉(方法)、加水(方法)
”洗衣机“ 加入属性和方法:漂洗(方法)、清洗(方法)、甩干(方法)
然后执行:
人.放衣服(方法)-> 人.加洗衣粉(方法)-> 人.加水(方法)-> 洗衣机.漂洗(方法)-> 洗衣机.清洗(方法)-> 洗衣机.甩干(方法)
封装(私有等级)
首先,我们得先知道封装是什么意思。顾名思义,封装就是将一个洞封起来不让别人看见。
可是如果将一个东西封起来,就说明除了将其封起来的那个人,其他人都不知道他内部是一个什么样子的结构,这样我们所封装好的东西就是一个不透明的小黑盒。虽然外人不知道这里面是一个什么样子的构造,但是我们可以通过作者提供的一些手段来应用这个东西。
这样的好处首先就是提供了代码的安全性,使外界对里面的东西访问受限,这样就保证了内部的一些重要的必要数据不被修改;并且也大大提高了代码的复用性,可以使各种各样的东西进行应用;通过封装,带来的高内聚和低耦合,使用不同对象、不同模块之间能更好的协同,同时便于修改,增强代码的可维护性。
这在Java中主要是通过类向外界提供set和get的方式了获取内部相应的数据,这样就不会暴露内部的一些限制条件。
public class car{
private int weight;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}像是这样,我就封装了一个汽车类型,并且用get和set方法来限制了他人直接对于数据的访问。
继承(父子类,重写)
我们都知道Java是一门面向对象的程序,我们将所有的东西都归为不同的类里面,因此,我们看了眼通过不同的类来获得我们所想要的东西。
然而如果一个类和另一个类的关系很大,那么我们就可以将这两个类的共同点定义成一个类这就是 父类,而那两个就成了他的子类。
我们可以通过继承的方式来将父类的节点进行一个导入,使得子类也可以运用分类的变量和方法,但是这并不完全是这样的。
extends
public class car{
private int weight;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public car() {
}
}
public class benChi extends car{
private int price;
public int getPrice() {
return price;
}
public benChi(int price) {
this.price = price;
}
}在Java继承可以使用 extends 关键字来实现,其中Java规定了java.lang.Object 类作为所有的类直接或间接的父类(当类没有继承其他类时,java默认继承Object类,当类继承了其他类时,可以向上追溯,最终继承的类就是Object类)。
当然,我们还需要注意
- 子类无法继承 private 修饰的属性和方法
- 子类和父类在同一包下,可以继承 default 权限的属性方法
- 子类可以对父类进行扩展,拥有自己的属性和方法
- 子类可以重写父类的方法(前提是可以继承到这个方法)(多态的体现)
多态
所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定。所以程序就需要应对不同情况来处理赋予不同的类。
重载
对于面向对象而已,多态分为编译时多态和运行时多态。其中编辑时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编辑之后会变成两个不同的函数,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是我们所说的多态性。
实际这种就是同名但是方法中的参数类型或个数不同,实现了静态的多态,其实就是重载。
String a_toString(int a)
{
return a.toString();
}
String a_toString(float a)
{
return a.toString();
}重写
这就是我之前所说的那样,这样我们就可以应用父类和子类定义的同名的变量和方法了,但是假如父类没有定义,子类定义了的话,相应的子类也将无法使用他们独有的变量和方法。
这种父类和子类同名同参的方法其实就属于一种重写。
向上转换
实现多态的条件之一就是,必须要有向上转换的能力。那么什么叫做向上转换呢?其实非常的简单,当我们不知道某一个东西的时候,但是我们知道这个东西是包含在哪一个父类里面时,我们就可以用父类来声明这一个变量,然后再用相应的子类来为其开辟内存,就像下面这样:
Car bigG = new benChi(); 当你使用父类引用指向子类的时候,其实jvm已经使用了编译器产生的类型信息调整转换了。
这里你可以这样理解,相当于把不是父类中含有的函数从虚拟函数表中设置为不可见的。注意有可能虚拟函数表中有些函数地址由于在子类中已经被改写了,所以对象虚拟函数表中虚拟函数项目地址已经被设置为子类中完成的方法体的地址了。