面向对象的三大特征
面向对象的三大特征分别是:封装、继承、多态
封装
封装在Java中的体现:
1.方法就是一种封装
2.关键字private 也是一种封装
3.封装就是将一些细节信息隐藏起来,对外接不可见
public class method {
public static void main(String[] args) {
int[] array = {5 , 15 , 20 , 25};
int max = getMax(array);
System.out.println("最大值:" + max);
}
//传入数组,返回其中的最大值
public static int getMax(int[] array){
for(int i = 1 ; i < array.length; i++) {
if(array[i] > max) {
max = array[i];
}
}
return max;
}
}
public class Student {
private String name; //自己的名字
public String getName(){
return age;
}
public String setName(String name){
this.name = name;
}
}
public class Demo1Person {
public static void main(String[] args){
Student student1 = new Student();
student1.setAge(20);
Student student2 = new Student();
student2.setAge(22);
}
}
继承
概述:
继承就要解决的问题就是"共性抽取"。
特点:
1. 子类可以拥有父亲的"内容"。
2. 子类还可以拥有自己专有内容。
3. Java语言是【单继承】的。
解释:
一个类的**直接**父类只能由一个。
4. Java语言可以多级继承
5. 一个子类的父类是唯一的,但是一个父类可以拥有很多子类。
备注:
1.继承是多态的前提,如果没有继承,就没有多态。
2.在继承的关系中,"子类就是一个父类",也就是说,子类可以当作父类看待
例如:
父类是员工,子类是讲师,那么"讲师就是一个员工"。关系:is~a
3.在父子类得继承当中,如果成员变量重名,则创建子类对象时,访问得方式有俩种:
- 直接通过子类对象访问成员变量:
等号左边是谁,就优先访问谁,没有则向上查找。
- 间接通过成员方法访问成员变量;
方法属于谁,就优先用谁,没有则向上找。
4.区分子类方法中重名的三种
局部变量:直接写
本类的成员变量:this.成员变量名;
父类的成员变量: super.成员变量名;
5.继承中成员方法的访问特点
在父子类的继承关系当中,创建子类对象,访问成员方法的规则
创建的对象是谁,就优先用谁,如果没有在向上查找
注意事项:
无论是成员方法还是成员变量,如果没有都是向上查找,绝对不会向下找子类的。
6.继承中方法的覆盖重写
概念:
重写( overRead ):
在继承关系当中,方法的名称一样,参数列表也一样
备注:
重载( overLoad ):方法名称一样,参数列表不一样
重写( overRead ):方法名称一样,参数列表一样
特点:
创建的是子类对象,就优先使用子类方法。
注意事项:
- 必须保证父子类之间的方法名称一致,参数列表也相同
@Override:写在方法前面,用来检测是不是有效的正确的覆盖重写
这个注解就算不写,只要满足要求,也是正确的方法覆盖重写。
- 子类方法的返回值必须小于等于父类方法的返回值范围。
前提:Object类是所有类的公共最高父类(祖宗类):
java.lang.String就是Object的子类。
- 子类方法的权限必须【大于等于】父类方法的权限修饰符。
前提:public > protected > (default) > private
备注:(default)不是关键字default,而是什么都不写,留空。
7.继承中构造方法的访问特点:
- 子类构造方法的当中,有一个默认的隐含的"super();"调用,所以一定是先调用父类构造,后执行的子类构造
- 子类构造可以通过super关键字来调用父类重载构造。
- super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次super构造。
总结:子类必须调用父类构造方法,不写默认第一行也是super,写了则用写的指定super调用,super只能由一个。还必须是第一个
8.super关键字的三种用法
- 在子类的成员变量中,访问父类的成员变量。
- 在子类的成员方法中,访问父类的成员方法。
- 在子类的构造方法中,访问父类的构造方法。
9.super用来访问父类内容,this用来访问本类内容。
10.this关键字的三种用法
1.在本类的成员方法中,访问本类的成员变量。
2.在本类的成员方法中,访问本类的另一个成员方法
3.在本类的构造方法中,访问本类的另一个构造方法
例如:
```Java
public class FU{
public Fu(){
this(123); //本类的无参构造,调用本类的有参构造。
}
public Fu(int num){
}
}
```
注意:
1.this(...)调用也必须是方法的第一个语句,唯一一个。
2.super和this俩个构造调用,不能同时调用
格式:
public class 父类名称{
...
}
public class 子类名称 extends 父类名称 {
...
}
案例:
public class People {
public String name; // 姓名
public int age; // 年龄
public String sex; // 性别
public String sn; // 身份证号
public People(String name, int age, String sex, String sn) {
this.name = name;
this.age = age;
this.sex = sex;
this.sn = sn;
}
public String toString() {
return "姓名:" + name + "\n年龄:" + age + "\n性别:" + sex + "\n身份证号:" + sn;
}
}
public class Student extends People {
private String stuNo; // 学号
private String department; // 所学专业
public Student(String name, int age, String sex, String sn, String stuno, String department) {
super(name, age, sex, sn); // 调用父类中的构造方法
this.stuNo = stuno;
this.department = department;
}
public String toString() {
return "姓名:" + name + "\n年龄:" + age + "\n性别:" + sex + "\n身份证号:" + sn + "\n学号:" + stuNo + "\n所学专业:" + department;
}
}
public class Teacher extends People {
private int tYear; // 教龄
private String tDept; // 所教专业
public Teacher(String name, int age, String sex, String sn, int tYear, String tDept) {
super(name, age, sex, sn); // 调用父类中的构造方法
this.tYear = tYear;
this.tDept = tDept;
}
public String toString() {
return "姓名:" + name + "\n年龄:" + age + "\n性别:" + sex + "\n身份证号:" + sn + "\n教龄:" + tYear + "\n所教专业:" + tDept;
}
}
public class PeopleTest {
public static void main(String[] args) {
// 创建Student类对象
People stuPeople = new Student("王丽丽", 23, "女", "410521198902145589", "00001", "计算机应用与技术");
System.out.println("----------------学生信息---------------------");
System.out.println(stuPeople);
// 创建Teacher类对象
People teaPeople = new Teacher("张文", 30, "男", "410521198203128847", 5, "计算机应用与技术");
System.out.println("----------------教师信息----------------------");
System.out.println(teaPeople);
}
}
运行结果:
----------------学生信息---------------------
姓名:王丽丽
年龄:23
性别:女
身份证号:410521198902145589
学号:00001
所学专业:计算机应用与技术
----------------教师信息----------------------
姓名:张文
年龄:30
性别:男
身份证号:410521198203128847
教龄:5
所教专业:计算机应用与技术
继承的优缺点
在面向对象语言中,继承是必不可少的、非常优秀的语言机制,它有如下优点:
- 实现代码共享,减少创建类的工作量,使子类可以拥有父类的方法和属性。
- 提高代码维护性和可重用性。
- 提高代码的可扩展性,更好的实现父类的方法。
自然界的所有事物都是优点和缺点并存的,继承的缺点如下:
- 继承是侵入性的。只要继承,就必须拥有父类的属性和方法。
- 降低代码灵活性。子类拥有父类的属性和方法后多了些约束。
- 增强代码耦合性(开发项目的原则为高内聚低耦合)。当父类的常量、变量和方法被修改时,需要考虑子类的修改,有可能会导致大段的代码需要重构。
多态
前提:
extends继承或者implements实现,是多态性的前提。
一个对象拥有多种形态,也就是:对象的多态性。
概念:
代码当中体现多态性,其实就是一句话,父类引用指向子类对象。
格式:
父类名称 对象名 = new 子类名称();
或者:
接口名称 对象名 = new 实现类名称();
访问成员变量的俩种方式:
1.直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上查找。
2.间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上查找。
访问成员方法的方式:
父子都有,优先子类
注意:
成员方法:编译看左边,运行看右边。
成员变量:编译看左边,运行还看左边。
使用多态的好处:
无论右边new的时候换成哪个子类对象,等号左边调用方法都不会变化。
对象的向上转型:
对象的向上转型,其实就是多态写法:
格式:
父类名称 对象名 = new 子类名称();
含义:
右侧创建一个子类对象,把它当做父类来看待使用。
注意事项:
向上转型一定是安全的。从小范围转向大范围
类似于:
double num = 100; //正确 int-->double,自动类型转换
弊端:
对象一旦向上转型为父类,那么就无法调用子类原本特有的内容。
解决方法:
用对象向下转型【还原】
对象的向下转型:
对象的向下转型,其实是一个【还原】动作
格式:
子类名称 对象名 = (子类名称)父类对象;
含义:
将父类对象,还原成为本来的子类对象。
例如:
Animal animal = new Cat();
Cat cat = (Cat) animal;
注意事项:
1.必须保证对象创建的时候,就是猫,才能向下转型
2.如果对象创建的时候,本来是猫,非要向下转型变成猫,就会报错。错误类型:ClassCastException
instanceof关键字:
格式:
对象 instanceof 类型;
得到一个Boolean值结构,也就是判断前面的对象是否是后面类型的实例
案例:
public class Figure {
double dim1;
double dim2;
Figure(double d1, double d2) {
// 有参的构造方法
this.dim1 = d1;
this.dim2 = d2;
}
double area() {
// 用于计算对象的面积
System.out.println("父类中计算对象面积的方法,没有实际意义,需要在子类中重写。");
return 0;
}
}
public class Rectangle extends Figure {
Rectangle(double d1, double d2) {
super(d1, d2);
}
double area() {
System.out.println("长方形的面积:");
return super.dim1 * super.dim2;
}
}
public class Triangle extends Figure {
Triangle(double d1, double d2) {
super(d1, d2);
}
double area() {
System.out.println("三角形的面积:");
return super.dim1 * super.dim2 / 2;
}
}
public class Test {
public static void main(String[] args) {
Figure figure; // 声明Figure类的变量
figure = new Rectangle(9, 9);
System.out.println(figure.area());
System.out.println("===============================");
figure = new Triangle(6, 8);
System.out.println(figure.area());
System.out.println("===============================");
figure = new Figure(10, 10);
System.out.println(figure.area());
}
}
执行结果:
长方形的面积:
81.0
===============================
三角形的面积:
24.0
===============================
父类中计算对象面积的方法,没有实际意义,需要在子类中重写。
0.0
注:
- 当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
- 多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
这篇笔记部分案例代码引用于 “C语言中文网”