Java面向对象的三大特性——封装、继承、多态
这是逛了几年blog第一次写blog,不知不觉已经毕业了,进入公司实习发现自己的java基础很差,虽然都知道一点,但是无法深入理解,半吊子的感觉很不好,所以尝试重新学一遍,并记录下来以供以后参考,欢迎大家指正错误,互相交流。
1.封装
1.1封装的定义
封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口。
1.2为什么要使用封装
用private把类的细节与外界隔离起来,从而实现数据项和方法的隐藏,而要访问这些数据项和方法唯一的途径就是通过类本身,类才有资格调用它所拥有的资源(方法,数据项属性等等)。所以数据的安全性提高了,而封装成工具类后大大增加了代码的重用性。
举个例子:
public class Student {
//我们创建一个学生类
//定义学生的基本属性
//学号
private int id;
//姓名
private String name;
//性别
private String sex;
//年龄
private int age;
//获取学号
public int getId() {
return id;
}
//修改学号
public void setId(int id) {
this.id = id;
}
//后面get,set方法以此类推
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
在代码中可以看见由于属性被private定义,其他类不可直接操作属性,只用使用get/set方法去获取或是改变属性。
2.继承
2.1继承的定义
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
2.2为什么需要继承
同样我们边看代码边来理解,以动物园里的老虎狮子为例。
老虎类:
public class Tiger {
//编号
private int id;
//名字
private String name;
//定义有参构造方法
public Tiger(int id,String name){
this.id=id;
this.name=name;
}
//再来定义老虎的行为方法
public void eat(){
System.out.println(name+"正在吃东西");
}
public void sleep(){
System.out.println(name+"正在睡觉");
}
}
狮子类:
public class Lion {
//编号
private int id;
//名字
private String name;
//定义有参构造方法
public Lion(int id,String name){
this.id=id;
this.name=name;
}
//再来定义狮子的行为方法
public void eat(){
System.out.println(name+"正在吃东西");
}
public void sleep(){
System.out.println(name+"正在睡觉");
}
}
虽然不涉及具体功能,但是对比两段代码我们不难看出狮子和老虎的属性及行为是一样的,代码重复,所以代码量就会变大且臃肿,以至于后期维护困难。这个时候,父类继承就很好的解决问题了,我们从两段代码中提取公共部分。
公共父类:动物类
public class Animal {
private int id;
private String name;
public Animal(int id,String name){
this.id=id;
this.name=name;
}
public void eat(){
System.out.println(name+"正在吃东西");
}
public void sleep(){
System.out.println(name+"正在睡觉");
}
}
这个Animal类就可以作为一个父类,然后企鹅类和老鼠类继承这个类之后,就具有父类当中的属性和方法,子类就不会存在重复的代码,维护性也提高,代码也更加简洁,提高代码的复用性(复用性主要是可以多次使用,不用再多次写同样的代码) 继承之后的代码:
老虎类:
public class Tiger extends Animal {
public Tiger(int id, String name) {
super(id, name);
}
}
狮子类:
public class Lion extends Animal {
public Lion(int id, String name) {
super(id, name);
}
}
2.3继承类型
| 类型 | 例子 |
|---|---|
| 单继承 | public class A{…} public class B extends A{…} |
| 多重继承 | public class A{…} public class B extends A{…} public class C extends B{…} |
| 不同类继承同一父类 | public class A{…} public class B extends A{…} public class C extends A{…} |
| 多继承(不支持) | public class A{…} public class B{…} public class C extends A,B{…} |
值得一提的是java虽然不支持多继承,但是可以使用接口来实现多继承机制,使用关键字extends而不是implement会实现多继承机制,如:public interface A extends InterfaceB,InterfaceC;
3.多态
3.1多态的定义
指一个引用(类型)在不同的情况下的多种状态。也可以理解为,多态是指通过指向父类的指针,来调用在不同子类中实现的方法。
3.2为什么需要多态
我们刚刚知道了封装会使代码模块化,而继承使模块化的代码扩展,而多态会进一步使代码的复用性增强,同时解决项目的紧耦合问题,提高代码的可扩展性,简单来说就是向后兼容,提高代码的可扩充性和可维护性。
我们还是拿动物园的狮子老虎来举个例子,当饲养员拿出肉来喂老虎和狮子,虽然同样是吃肉,但是饭量大小不一样,饲养员会先判断这是老虎还是狮子,然后再判断吃多少,这样的重复判断就很浪费时间,这样就要像个办法让饲养员拿出足够斤数的肉就能判断是哪种动物
我们创建一个动物类:
public class Animal {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void eat(){
System.out.println("不知道吃多少");
}
}
然后创建老虎类和狮子类:
public class Tiger extends Animal {
//重写方法
public void eat(){
System.out.println("我要吃5kg");
}
}
public class Lion extends Animal {
public void eat(){
System.out.println("我要吃10kg");
}
}
再创建饲养员类:
public class Breeder {
// 给动物喂食物,如果没有多态,他要写给老虎喂食和给狮子喂食两个方法
// 有了多态,以后即使再来好多动物,用这一个函数就可以了
public void feed(Animal an) {
an.eat();
}
}
最后我们在main方法里测试一下
public class Main{
public static void main(String[] arg){
Breeder breeder=new Breeder();
breeder.feed(new Tiger());
breeder.feed(new Lion());
}
}
结果如下: