Java复习知识点九:
- 访问修饰符
- 封装
- 继承
- super关键字
- super和this的比较
- 重载和重写的比较
- 多态向上转型
- 多态向下转型
1、访问修饰符
java提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围):
- 公开级别:用public修饰,对外公开
- 受保护级别:用protected修饰.对子类和同一个包中的类公开
- 默认级别:没有修饰符号,向同一个包的类公开.
- 私有级别:用private修饰,只有类本身可以访问,不对外公开.
使用的注意事项:
- 修饰符可以用来修饰类中的属性,成员方法以及类
- 只有 默认和public才可以修饰类!
2、封装
基本介绍:
面向对象编程的三大特征:封装、继承 和 多态
封装(encapsulation) 就是把抽象出的数据[属性] 和 对数据的操作[方法]封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作[方法],才能对数据进行操作。
封装的好处:
- 隐藏实现细节
- 只能通过规定的方法访问数据;
- 可以对数据进行验证,保证安全合理
2.1 封装的实现步骤
-
将属性进行私有化【不能直接修改属性】
-
提供一个公共的(public)set方法,用于对属性判断并赋值
public void setXxx(类型 参数名){//Xxx表示某个属性 //加入数据验证的业务逻辑 属性 = 参数名 }
-
提供一个公共的(public)get方法,用于获取属性的值
public 数据类型getXxx(){//权限判断,Xx某个属性 return xx; }
快速入门:
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public void getName(String name){
}
}
3、继承
基本介绍:
**继承可以解决代码的复用性问题。**多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法即可,子类只需要通过 extends 关键字来声明继承父类即可
继承的基本语法:
class 子类 extends 父类{
}
- 子类就会自动拥有父类定义的属性和方法
- 父类又叫超类,基类。
- 子类又叫派生类。
3.1 继承的使用细节
- 子类继承了父类的所有属性和方法,但是私有属性不能在子类中直接访问,要通过公共的方法去访问
- 子类必须调用父类的构造器完成类的初始化
- 不管使用子类的那个构造器,默认情况下总会去调用父类的无参构造器
- 如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定(使用super)使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
- super在使用时,需要放在构造器的第一行(super();只能在构造器中使用)
- super()和 this()都只能放在构造器的第一行,因此这两个方法不能共存在一个构造器中
- **java中所有类都是Object类的子类,**Object是所有类的基类(父类)
- 父类构造器的调用不限于直接父类!将一直往上追溯到Object类(顶级父类)
- 子类在java中最多只能继承一个父类(指直接继承),即java中是单继承机制
- 子类和父类之间必须满足 is-a 的逻辑关系。(猫是一个动物)
3.2 继承的本质分析
当访问属性时,会从子类属性开始查找,子类没有,则找上级父类
4、super关键字
基本介绍:
super代表父类的引用,用于访问父类的属性、方法、构造器
基本语法:
- 访问父类的属性,但不能访问父类的private属性;super.属性名
- 访问父类的方法,不能访问父类的private方法;super.方法名(形参列表);
- 访问父类的构造器,super(参数列表)。只能放在构造器的第一行,并且只能出现一次
使用细节:
- 调用父类的构造器的好处 (分工明确,父类属性由父类初始化,子类的属性由子类初始化)
- 当子类重写了父类的成员(重名时),为了访问父类成员,必须通过super
- super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类中都有同名的成员,使用super访问遵循就近原则;子 -> 父 -> 爷
5、super和this的比较
6、方法的重写
基本介绍:
简单的说:**方法覆盖(重写)**就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的那个方法
使用细节:
两同 两小 一大
- 子类的方法的参数,方法名称,要和父类方法的参数,方法名称完全一样。(两同)
- 子类方法的返回值类型要和父类返回值类型一致,或者是父类返回值类型的子类。比如:父类 返回类型是Object,子类返回类型是String (小)
- 子类抛出异常小于等于父类方法抛出异常,(小)
- 子类方法不能缩小父类方法的访问权限。比如:父类: void sayOk(){},子类不能是 public void sayOk(){};(大)
7、重载和重写的比较
8、多态
方法或对象具有多种形态。多态是建立在封装和继承基础之上的。
多态的前提是:两个类存在继承关系
多态的具体体现:
-
方法的多态:重写和重载就体现多态。比如:传入不同的参数,就会调用不同方法,就体现多态(重载)。
-
对象的多态(核心):
- 一个对象的编译类型和运行类型可以不一致
- 编译类型在定义对象时,就确定了,不能改变
- 运行类型是可以变化的。
- 编译看 =号 左边,运行看 =号 右边
Animal animal = new Dog(); //Animal是编译类型,运行类型是Dog animal = new Cat();//animal的运行类型变成了Cat,animal的编译类型任然是Animal
9、多态的向上转型
多态的向上转型:
- 本质:父类的引用指向了子类的对象
- 语法: 父类类型 引用名称 = new 子类类型( );
- 特点:编译类型看左边,运行类型看右边
- 可以调用父类中的所有成员(需遵守访问权限)
- 不能调用子类中特有的成员
- 因为在编译阶段,能调用那些成员,是由编译类型决定的
- 最终运行效果看子类的具体实现
注意:在向上转型中,属性没有重写之说!属性的值看编译类型
10、多态的向下转型
多态的向下转型:
-
语法:子类类型 引用名 = (子类类型)父类引用
Animal animal = new Cat(); //向下转型 Cat cat = (Cat)animal;
-
只能强转父类的引用,不能强转父类的对象
-
要求父类的引用必须指向的是当前目标类型的对象
-
当向下转型后,可以调用子类类型中所有的成员
-
instanceOf 比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型
11、Java动态绑定机制
-
当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
-
当调用对象属性时,没有动态绑定机制,哪里声明哪里使用
public class DynamicBinding { public static void main(String[] args){ A a = new B();//向上转型 System.out.println(a.sum());//调用父类的sum()后,会调用子类的getI();即动态绑定机制 System.out.println(a.sum1());//调用父类的sum1()后,会使用父类的属性i;属性没有动态绑定机制 //30 //20 } } 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; } }
12、多态数组
多态的应用:
定义一个对象数组,数组类型为父类类型,里面保存的实际元素为子类类型
父类:Person
子类:Student、Teacher
调用子类特有方法:
使用instanceOf判断对象运行类型
13、多态参数
多态的应用:
方法定义的形参类型为父类类型,实参类型允许为子类类型