- 封装
利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立个体。数据被保护在抽象数据类型的内部,尽可能的隐藏内部的细节,只保留一些对外的接口使之于外部发生联系。用户无需知道内部是如何实现的,但可以通过对外提供的接口来访问该对象。
优点:
- 减少耦合,可以独立的开发、测试、优化、使用、理解和修改
- 减轻维护的负担:可以更加容易被开发者理解,并且在调试的时候不会影响其他模块
- 有效的调节性能:可以通过剖析确定是哪些影响了系统性能
- 提高的软件的可重用性。
- 降低了构建大型系统的风险:即使系统不可用,某些模块功能还是可用的。
public class Student {
/**
* 学生num
*/
private String studentNum;
/**
* 年龄
*/
private String age;
/**
* 学校
*/
private String school;
/**
* 学校班级
*/
private String schoolClass;
/**
* 电话
*/
private Integer phone;
/**
* 性别
*/
private int gender;
public String getStudentNum() {
return studentNum;
}
public String getAge() {
return age;
}
public String getSchool() {
return school;
}
public String getSchoolClass() {
return schoolClass;
}
// 性别的属性为Integer,但是通过get方法返回是String,外部感知不到
public String getGender() {
return gender==0?"男":"女";
}
// Phone 电话号码只能在管理员才能返回
public Integer getPhone(boolean isAdmin){
if (isAdmin){
return phone;
}
return null;
}
}
- 继承
继承是 is - a 的关系,例如:猫是动物,因此猫可以继承自动物,使用动物中非私有的属性和方法。
继承应该遵循里氏替换原则,子类对象必须能够全部替换父类对象。
// 向上转型,父类引用指向子类对象
Animal animal = new Cat();
- 多态
多态分为 编译时多态 和 运行时多态
- 编译时多态:方法的重载
- 运行时多态:程序中定义的对象引用所指向的具体类型在运行期间才能确定
运行时多态的三个条件:
继承
覆盖(方法的重写)
向上转型
代码示例:
public abstract class Animal{
public abstract void eat(){
System.out.println("动物在吃东西");
}
}
public class Cat extends Animal {
@Override
public void eat(){
System.out.println("猫在吃东西");
}
}
public class Dog extends Animal {
@Override
public void eat(){
System.out.println("狗在吃东西");
}
}
public class test{
public static void main(String [] args]){
List<Animal> animals = new ArrayList();
animal.add(new Cat());
animal.add(new Dog());
for(Animal animal:animals){
// 在运行的时候才知道是哪个具体的类。
animal.eat();
}
}
}