面向对象三大特征——封装,继承,多态
面向对象三大特征:
- 封装
- 继承
- 多态
接下来让我们一一讲解:
封装
概念:
- 对数据的隐藏,禁止直接访问一个对象中数据的实际情况,通过操作接口来访问,称为信息隐藏
要求:
- “高内聚,低耦合”
- 高内聚:类的内部数据操作细节自己完成,不允许外部干涉
- 低耦合:仅暴漏少量方法给外部使用
核心词汇:
代码语言:javascript复制private
使用private定义类内属性后,不能直接在外部使用属性,只能在类内使用属性
private定义:
代码语言:javascript复制public class Student {
//私有属性:
private String name;
private int age;
private String sex;
//提供对外的public方法:
public String showName(){
return this.name;
}
public void changeName(String name){
this.name = name;
}
}
通常用private定义类内属性,再创建public方法调用类属性:
代码语言:javascript复制public class application {
public static void main(String[] args) {
Student xiaohong = new Student();
xiaohong.changeName("小红");
System.out.println(xiaohong.showName());
}
}
封装的功能:
- 提高程序安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统可维护性增加
继承
本质:
- 对某一批类的抽象,从而实现对现实世界更好的建模
使用方法:
代码语言:javascript复制public class 子类 extends 父类{
.......
}
注意点:
- java中只有单继承,没有多继承
- 所有类统一拥有一个父类—Object类
- 继承只是类的一种关系,除此之外还有依赖,组合,聚合等关系
- 子类继承父类的public和protected属性,不继承private属性(方法同理)
例子:
代码语言:javascript复制//main函数
public class application {
public static void main(String[] args) {
Person person = new Person();
person.say();
Student student = new Student();
student.say();
}
}
代码语言:javascript复制//父函数
public class Person {
public int debt;
public int objects;
private int money;
public void say(){
System.out.println("my nameHead is Hou");
}
}
代码语言:javascript复制//子函数
public class Student extends Person{
}
结果:
代码语言:javascript复制my nameHead is Hou
my nameHead is Hou
从上面我们可以看到即使子函数中没有任何代码,但子函数仍旧可以继承父函数的代码来实现main函数的要求
继承方法快捷键:
代码语言:javascript复制ctrl H
继承扩展—super
原版name,this.name,super.name的区别:
- name:指外部输入的name
- this.name:类的name属性
- super.name:父的name属性
//main函数
public class application {
public static void main(String[] args) {
Student student = new Student();
student.showName("侯");
student.showManner();
}
}
代码语言:javascript复制//父函数
public class People {
//父类姓名
String name = "HOU";
//方法
public void plan(){
System.out.println("people调用");
}
}
代码语言:javascript复制//子函数
public class Student extends People{
//子类姓名
String name = "hou";
//调用姓名:
public void showName(String name){
//调用输入的name
System.out.println(name);
//调用student的name
System.out.println(this.name);
//调用people的name
System.out.println(super.name);
}
//调用方法:
public void showManner(){
this.plan();
super.plan();
}
//方法
public void plan(){
System.out.println("student调用");
}
}
结果:
代码语言:javascript复制侯
hou
HOU
student调用
people调用
注意:
- 当调用子类时,先调用父类构造器,在调用子类构造器
- super必须出现在子类的方法或构造方法中(系统自动)
- 当super调用父类的构造方法,必须在子类构造方法的第一个
- 当父类不包含无参构造方法时,必须在子类构造方法中的第一个写入super()构造方法;或者为父类添加无参构造方法
- super和this不能同时调用构造方法
构造方法:
- this():本类的构造
- super():父类的构造
方法重写
重写均为方法的重写
重写的定义:
- 子类方法和父类方法结构一致
- 子类方法和父类方法的方法体不一样
重写的条件:
- 需要有继承关系,子类重写父类的方法
- 方法名必须一样
- 参数列表必须一样
- 修饰符范围可以扩大但不能缩小: public>protected>default>private
- 抛出的异常范围可以缩小不能扩大
为什么要重写方法:
- 父类的功能,子类不一定需要
- 父类的功能,子类不一定满足
方法重写static和非static的区别:
- static:不属于方法重写,一切命令遵循左边数据类型决定
- 非static:属于方法重写,一切命令遵循右侧数据类型决定
代码演示:
代码语言:javascript复制//main函数
public class application {
public static void main(String[] args) {
A a = new A();
B b =new A();
//属于重写,a重写了b的plan1
a.plan1();
b.plan1();
//static只和左边定义类型油管
a.plan2();
b.plan2();
}
}
代码语言:javascript复制//父函数
public class B {
//非static方法:
public void plan1(){
System.out.println("i am b plan1");
}
//static方法:
public static void plan2(){
System.out.println("i am b plan2");
}
}
代码语言:javascript复制//子函数
public class A extends B{
//非static方法:
public void plan1(){
System.out.println("i am a plan1");
}
//static方法:
public static void plan2(){
System.out.println("i am a plan2");
}
}
多态
一个对象的实际模型是确定的,但可以指向的引用模型是不确定的:
多态存在的条件:
- 有继承关系
- 子类重写父类的方法
- 父类引用指向子类对象
注意:
- 多态只是方法的多态
父类定义的变量 可以指向 子类模型
代码语言:javascript复制父类 name = new 子类();
对象所能执行的方法取决于左侧的类型:
- 父类可以使用父类子类都存在的方法:使用子类的版本
- 父类可以使用只有父类存在的方法:使用父类的版本
- 父类不可以使用只有子类存在的方法;但可以通过转换((子类)name).方法()来实现
判断语法:instanceof
作用:
- 判断父类子类是否属于一条继承线上
语法:
代码语言:javascript复制父类 instanceof 子类
结果:
代码语言:javascript复制true
false
例如:
object->people->student
object->people->teacher
存在上述两条继承线,则:
代码语言:javascript复制student instanceof object -> true
代码语言:javascript复制student instanceof teacher -> false
类型转换
这里对类型转换不做过多赘述:
- 父类引用指向子类的对象
- 把子类转换为父类,向上转型;属于自然转换,但可能丢失部分子类独占的方法
- 把父类转换为子类,向下转型;属于强制转换
- 方便方法的调用,减少重复代码的出现
结束语
好的,针对面向对象的三大特征就概述到这里