封装
概念
是一种屏障,作用为防止对象数据被外界任意访问
步骤
- 属性私有化:
- 语法:private 数据类型 属性名;
- 属性私有化后的属性只有定义该属性的类内部可以使用,其他类无法访问。
- 可以选择性的对属性进行私有化操作,但是通常情况下,所有属性都应该参与私有化。
- 提供取值(getter)、赋值(setter)的方法通道
- getter:get+属性名(属性名首字母大写)
- 如果属性类型为布尔类型:is+属性名(首字母大写)
- 有返回值,无参数
- 返回值类型与对应属性保持一致
- setter:set+属性名(属性名首字母大写)
- 无返回值有参数
- getter:get+属性名(属性名首字母大写)
可以选择性的为私有化属性提供getter、setter方法,但是通常情况下,都需要具备。
使用
属性封装后,无法通过(对象名.属性名)方式访问属性,需要通过调佣方法实现。
语法: 取值:对象名.getXxx() 、 赋值:对象名.setXxx(实参);
访问修饰符
控制内容可被访问的范围
本类 | 同包 | 非同包子类 | 非同包非子类 | |
---|---|---|---|---|
private(私有的) | √ | |||
default(默认的) | √ | √ | ||
protected(受保护的) | √ | √ | √ | |
public(公开的) | √ | √ | √ | √ |
- default身为访问修饰符无法显示声明
- 只有public和default可以修饰类
- 四个访问修饰符都可以修饰属性、方法、构造
- 四个访问修饰符都无法修饰局部变量
对象的创建过程
- 给属性开辟空间、赋默认值(必须执行)
- 给属性赋初始值
- 执行构造内容,再次赋值
继承
实际开发中,类与类之间代码会出现冗余,处理方式为将重复代码提炼至第三个类,书写双方之间的继承关系
概念
将子类的共性内容进行抽取,生成父类,建立在继承关系下,子类可以继承拥有父类所有可被继承的内容。
语法
public class 子类类名 extends 父类类名{
}
使用
- 必须建立在is a关系上
- 子类可以拥有独有内容
- 父类无法访问子类独有内容
- 一个类在身为子类的同时仍可以是其他类的父类
- 子类可以继承拥有所有父类所有可被继承的内容
- 一个子类只能拥有一个直接父类
- 一个父类可以拥有多个直接子类
- 父类构造子类无法继承
- 父类的私有内容子类无法直接继承访问
方法重写
在继承关系下,如果子类不满足于父类提供的方法实现,则可以选择对方法实现进行重写
概念
子类对父类中继承过来的方法进行方法体的重写,简称方法重写
规则
-
方法名、参数列表、返回值类型必须与父类保持一致
-
访问修饰符必须与父类相同或者更宽
-
不允许抛出比父类更大或更多的异常
使用
方法重写后,子类对象会优先执行自身重写之后的内容
父类的作用:
1. 解决子类之间的代码冗余问题
2. 强制子类拥有某些内容
子类的内存结构
子类的内存空间由父类内容+独有内容构成
父类封装
父类将属性封装之后,子类无法直接通过对象名.属性名
的方式直接访问父类声明属性,必须通过对象名.getter()|对象名.setter()
的形式对属性进行访问
Super关键字
代表父类对象
super()
作用为调用父类构造内容
使用
- 通过实参列表决定调用的是哪个父类构造
- 必须写在构造方法有效代码第一行
- 无法与this()共存
- 子类构造第一行默认存在无参的super(),当手动调用super方法后或书写了this方法调用后,该默认存在的super()会失效。
- 可以借助super()实现在子类有参构造中为父类中声明的属性赋值的操作
1. 父类中正常声明有参构造 public class Animal { //特征:名字、年龄、性别 private String name; private int age; private String sex; public Animal(){} public Animal(String name,int age,String sex){ System.out.println("正在执行animal有参构造..."); this.name = name; this.age = age; this.sex = sex; } //getter、setter方法 ... //行为:吃饭、睡觉 ... } 2. 子类书写有参构造,将希望赋值的形参正常声明,内部调用super()利用对应的父类有参构造实现赋值 public class Dog extends Animal{ public Dog(){} public Dog(String name,int age,String sex){ //调用父类中的有参构造方法为父类中声明的属性赋值 super(name,age,sex); } }
super.
指明调用父类属性或方法
super.属性名
super.方法名(实参)
父类属性封装后,无法通过super.属性名调用父类属性
有继承关系的对象创建过程
-
给父|子类属性分配空间,赋默认值
-
给父类属性赋初始值
-
执行父类构造再次赋值
-
给子类属性赋初始值
-
执行子类构造再次赋值
多态
父类引用的多种具体值的不同形态
概念
父类引用可以指向不同的子类对象
语法:
父类引用名=子类对象;
父类类名 引用名=new 子类类名();
使用
- 实际创建的是子类对象
- 优先执行子类内容
- 无法访问子类独有内容
- 编译不通过
- 编译器关注的是引用类型,解释器关注的是实际对象类型
- 左边决定能做什么,右边决定谁来做
引用类型之间的类型转换
自动类型转换
父类引用=子类对象;
强制类型转换
子类类型=(子类类型)父类引用;
子类类名 引用名=(子类类名)父类引用名;
- 只能转向父类引用原本指向的子类类型
- 同级子类之间无法进行类型强转
多态的使用场景
1. 用于容器:将容器(变量、数组、集合等)类型声明为大类型,则内部可以存放不同的小类型对象
2. 用于参数:将方法形参类型声明为大类型,则传入实参时可以为不同子类对象
3. 用于返回值:将方法返回值类型声明为大类型,则可以实际return不同的子类对象
( 接收返回值时,也应该使用父类引用类型接收)
instanceof关键字
判断引用是否与指定类型兼容
语法:引用名 instanceof 类名
使用
-
子类对象可以被父类类型兼容
-
父类对象无法被子类类型兼容
-
同级子类之间无法兼容
大类型可以兼容小类型,但是小类型无法兼容大类型
多态的好处
-
更加贴合现实逻辑
-
提高代码扩展性
-
减少代码冗余
重点掌握
- 封装的步骤(getter、setter区别)
- 封装后的属性使用
- 四个访问修饰符及访问范围
- 对象的创建过程
- 继承的语法
- 继承的使用规则
- 方法重写的规则
- super()的使用
- 多态的概念
- 引用类型之间的强转
- 多态的三个使用场景
- instanceof关键字的语法和使用