面向对象的三大特性
- 一、封装private
-
- 1.1理解封装
- 1.2封装的好处
- 1.3实现
- 二、继承extend
-
- 2.1理解继承
- 2.2继承的本质
- 2.3继承的特点
- 三、多态
-
- 3.1理解多态
- 3.2多态的应用:
- 四、包结构
- 五、访问修饰符
- 六、static和this关键字
- 七、this和super的区别
- 八、重写(覆盖)和重载
-
- 8.1重载
- 8.2重写
- 九、Final
- 十、重写object类的equals方法
-
- 10.1.Object类的equals()方法
- 10.2.操作符==
- 十一、instanceof
封装和继承目的都是为了代码重用,多态目的是为了接口重用。
一、封装private
1.1理解封装
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
private是权限修饰符,私有的。
1.2封装的好处
- 便于使用者正确使用系统,防止错误修改属性
- 有助于系统之间的松耦合,提高系统独立性
- 提高软件的可重用性
- 降低了构建大型系统的风险
1.3实现
把类的成员属性和成员方法进行封装(私有化),然后提供公共的访问和使用的方法(get和set)。
(1)属性访问修饰符定义为私有:private。
(2)对外提供get和set方法。
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
二、继承extend
2.1理解继承
继承可以使用父类的所有属性和方法,可以在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建了新的类成为子类或派生类。被继承的成为基类。
继承有两种,一种是实现继承,另一种是接口继承。
- 实现继承:可以直接使用基类的属性和方法,无需额外编码。
- 接口继承:是指使用属性和方法的名称,但是子类必须提供实现的能力。
1.在多个子类中抽取相同的属性和方法,形成父类的属性和方法。
2.对父类成员的继承和使用(包含成员属性和成员方法)。
下面展示一些
继承的案例代码片
。
public class Car {
//汽车类(父类):车牌号、品牌、日租金
private String id;
private String type;
private int dayMoney;
//无参构造方法
public Car() {
}
//有参构造方法
public Car(String type, String id, int dayMoney) {
this.type = type;
this.id = id;
this.dayMoney = dayMoney;
}
//计算总租金的方法,定义了租赁天数和总租金
public double getMoney(int days){
int money=this.getDayMoney()*days;
return money;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String id() {
return id;
}
public void id(String id) {
this.id = id;
}
public int getDayMoney() {
return dayMoney;
}
public void setDayMoney(int dayMoney) {
this.dayMoney = dayMoney;
}
}
子类继承了父类的成员属性和成员方法
public class Bus extends Car {
//客车类(子类):车牌号、品牌、日租金,座位数
private String seatNum;
public Bus(String seatNum) {
this.seatNum = seatNum;
}
//无参构造方法
public Bus() {
}
//有参构造方法(继承了父类的成员属性)
public Bus(String type, String id, int dayMoney, String seatNum) {
super(type, id, dayMoney);
this.seatNum = seatNum;
}
//重写父类:计算总租金的方法(继承了父类的方法)
@Override
public double getMoney(int days){
int money=this.getDayMoney()*days;
if (days>=150){
money *=0.6;
}else if (days>=30){
money *=0.7;
}else if (days>=7){
money *=0.8;
}else if (days>=3){
money *=0.9;
}
return money;
}
public String getSeatNum() {
return seatNum;
}
public void setSeatNum(String seatNum) {
this.seatNum = seatNum;
}
}
2.2继承的本质
调用子类的构造方法是,会先调用父类的构造方法创建父类的对象(隐藏),然后再创建子类对象(显示)。所以,创建子类对象后,内存中既有子类对象,又有父类对象,这是extend关键字起的作用。
2.3继承的特点
- 父类的属性来自于各个子类共同的属性,子类也可以保留自己独特的属性和方法,子类可以继承(调用)父类的属性和方法。
- 子类和父类的关系:父类是一个大的分类范围,子类是一个小的分类范围。父类绝对包含子类。
- 单继承:子类只能有一个父类,java不支持多继承
- 继承是两个类之间产生关联关系的唯一的方式,为多态提供了前提
三、多态
3.1理解多态
多态就是对一个实例的相同方法在不同的情况下有不同表现形式。多态机制使得不同内部结构的对象可以共享相同的外部接口。这意味着,虽然不同类的内部操作不同,但是可以通过一个公共类,他们可以通过相同的方法给与调用。
通俗的理解:父类作为形参,子类类型作为实参。把子类的实例化对象赋值给父类的引用类型。
多态:父类的万子千孙的状态,多种状态,多态=继承+重写
3.2多态的应用:
1.父类作为方法的形参 (多态最常用的使用方式)
public void test(Object obj){
...
}
2.父类作为方法的返回值
public Object test(){
...
return obj;
}
四、包结构
在开发大型项目时,会有很多功能模块的具体划分,这是需要建立很多的类,将同一层级的类放在一个包中,可使程序的层级结构清晰,提高辨识度。
类似于在资源管理器中新建一个文件夹,有规律的存放和管理资源文件。
包命名规范:
- 包名由小写字母组成,不能以圆点开头或结尾
- 包名之前最好加上唯一的前缀,通常使用组织倒置的网络域名
- 包名后续部分依不同机构内部的规范不同而不同
导包:导入自己的包和系统包
java.lang包是java语言的核心,它提供了java中的基础类。(java.lang这个包属于系统包,该包中的类不用导入,例如System,String)
五、访问修饰符
下图中:受保护的情况(protected) :子类必须在同一个包中。
修饰符\作用域 | 同一个类中 | 同一个包中 | 子类中 | 任何地方 |
---|---|---|---|---|
private | 可以 | 不可以 | 不可以 | 不可以 |
默认修饰符 | 可以 | 可以 | 不可以 | 不可以 |
protected | 可以 | 可以 | 可以 | 不可以 |
public | 可以 | 可以 | 可以 | 可以 |
1.类的访问修饰符:
Public:对外公开
默认:所在包有效,包以外不能访问 --体现在构造方法上
2.成员访问修饰符(成员属性和成员方法)
Public:对外公开
Protected:受保护的,同一个包的子类可以访问。
默认:同一个包中可以访问
Private:只在当前类有效
六、static和this关键字
Static修饰的,属于类范围的,this代表当前对象。
Static修饰成员属性、方法和代码块。
七、this和super的区别
this:
1.本类成员方法中,访问本类成员变量,访问本类另一个成员方法
2.本类构造方法中,访问本类另一个构造方法
Super:
1.在子类成员方法中,访问父类成员变量和成员方法
2.在子类构造方法中,访问父类构造方法
本类的成员变量和局部变量重名,用this区分,
本类的成员变量和父类的变量重名,用super区分
八、重写(覆盖)和重载
8.1重载
同一个类中,方法名相同方法参数不同,典型应用:无参构造和有参构造。
目的:简化方法的调用,不用在方法名上刻意区分不同功能的方法。
8.2重写
子类覆盖父类的同名方法,参数相同,返回值相同,访问权限只能大于或等于父类方法的权限。
目的:功能的扩展
九、Final
修饰的变量称为常量,值不能被修改
修饰的方法不能被重写,保证安全性和稳定性
修饰的类不能被继承,避免功能被覆盖。
要想让一个类不被其它类继承:
1.用final修饰
2.构造方法私有化
十、重写object类的equals方法
10.1.Object类的equals()方法
比较两个对象是否是同一个对象,如果是则返回true。
Object类是所有类的父类,它的equals方法自然会被所有类继承,有一个子类String对equals方法进行了覆盖(重写),使其具有了新功能。
10.2.操作符==
简单数据类型或常量值,直接比较值。如1==2,“你好” == “你好”
引用类型,比较是否为同一个对象。
- (1)Object类的equals()方法与==没区别
- (2)Java.lang.String重写了equals()方法,把equals()方法的判断变为了判断其值
- (3)当有特殊需求,如认为属性相同即为同一对象时,需要重写equals()
总结:
- 1.基本数据类型数据值只能用= =
- 2.对于引用数据类型,= =和Object的equals方法是一样的。
- 3.由于String类对父类Object的equals方法的重写,导致==与equals唯一的区别在于:
String a = new String("你好");
String b = new String("你好");
System.out.println(a.equals(b));
System.out.println(a==b);
十一、instanceof
java中的instanceof运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例
使用格式: 对象 instanceof 类
使用解析:
- 形参 和实参 和 右边的类型
- 主要是看实参对象是否属于右边的类型