一、super关键字
(一)基本介绍
super代表父类的引用,用于访问父类的属性、方法、构造器
(二)基本语法
- 访问父类的属性,但不能访问父类的private属性
super.属性名; - 访问交类的方法,不能访问父类的private方法
super.方法名(参数列表) - 访问父类的构造器,只能放在构造器的第一句,只能出现一句!
super(参数列表);
(三)好处
- 调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子类初始化)
- 当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果
- super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则
二、封装(encapsulation)
(一)封装就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作[方法],才能对数据进行操作。
(二)封装的理解和好处:
1)隐藏实现细节
2)可以对数据进行验证,保证安全合理
(三)实现步骤:
1)将属性进行私有化private 【不能直接修改属性】
2)提供一个公共的(public)set方法,用于对属性判断并赋值
public void setXxx(类型参数名){
//加入数据验证的业务逻辑属性=参数名;
}
3)提供一个公共的(public)get方法,用于获取属性的值
public XX getXxx({//权限判断
return xx;
}
三、继承
(一)继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。
(二)继承的基本语法
class 子类 extends 父类{}
1)子类就会自动拥有父类定义的属性和方法
2)父类又叫超类、基类。
3)子类又叫派生类。
(三)使用细则
- 子类继承父类所有属性和方法,但私有属性和方法不能被子类直接访问,要通过公共的方法访问
- 子类必须调用父类的构造器,完成父类的初始化
- 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
- 如果希望指定去调用父类的某个构造器,则显式的调用一下
- super在使用时,需要放在构造器第一行
- super()和 this()都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
- java所有类都是Object的子类
- 父类构造器的调用不限于直接父类,将一直往上追溯到Object类
- 子类只能继承一个父类
- 不能滥用继承,子类和父类之间必须满足is-a的逻辑关系(例:student is a person)
四、多态
-
方法的多态
案例:(求和运算)
sum(a,b);
sum(a,b,c); -
对象的多态(核心,困难,重点)
(1)一个对象的编译类型和运行类型可以不一致
(2)编译类型在定义对象时,就确定了,不能改变
(3)运行类型是可以变化的
(4)编译类型看定义时=号的左边,运行类型看=号的右边
案例:
Animal animal = new Dog();
[animal编译类型是Animal,运行类型是Dog]
animal = new Cat();
[animal编译类型是Animal,运行类型是Cat] -
向上转型
本质:父类的引用指向子类的对象
语法:父类类型 引用名 = new 子类类型();
调用规则:
1)可以调用父类的所有成员(需遵守访问规则)
2)不能调用子类特有成员(编译类型决定可以调用哪些方法)
3)最终的运行效果看子类 -
向下转型
语法:子类类型 引用名 = (子类类型)父类引用;
调用规则:
1)只能强转父类的引用,不能强转父类的对象
2)要求父类的引用必须指向的是当前目标类型的对象
3)当向下转型后,可以调用子类类型中所有的成员
使用如下:
//向上转型,只能调用父类所有和父子类共有方法
Animal animal = new Dog();
//向下转型,可以调用子类特有方法
Dog dog = (Dog)animal;
五、动态绑定机制(十分重要)
类1 对象名 = 类2;
类1是对象的编译类型
类2是对象的运行类型
属性看编译类型,方法看运行类型(超级重要)
方法有动态绑定机制,属性没有。
- 当调用对象方法的时候,该方法会和该对象的内
存地址/运行类型绑定 - 当调用对象属性时,没有动态绑定机制,哪里声
明,那里使用
实例:
class A{
public int i = 10;
public int sum(){
return getI() + 10;
}
public int sum1(){
return i + 10;
}
public int getI(){
return i;
}
}
class B extends A{
public int i = 20;
public int getI(){
return i;
}
}
A a = new B();
System.out.println(a.sum());//20 + 10
System.out.println(a.sum1());//10 + 10
//如果注释掉B的getI()方法
//System.out.println(a.sum());//10 + 10
特别说明
本文章是个人整理的学习笔记,参考b站韩顺平老师的课程(【零基础 快速学Java】韩顺平 零基础30天学会Java)。老师讲的非常好,有兴趣的可以去看一下。