为什么要学封装?
现有对象的属性数据没有完善的校验检查机制,可以随意通过“对象名.属性名”的形式访问,最终可能导致数据不完整,不安全。
属性隐藏:private(私有的)
private是一个修饰符,可以修饰属性、方法、构造方法 ,含义与public相反
private修饰的内容,只能在本类内部代码使用,类之外无法访问
隐藏属性: 一般代码开发时,对象的属性全部私有
提供公开的属性访问通道:set(入口)—get(出口)
1. 提供公开的方法设置属性值:
① 语法: public void set属性名(参数类型 参数名){
设置属性值的代码
}
② 方法名通常是 set + 属性名首字母大写
setName setAge
③ 参数类型 : 由设置的属性类型决定
④ 案例 : 为name属性设置值
public void setName(String name){
this.name = name;
}
注意: 属性名首字母必须小写,必须由两个以上字符构成
2. 提供公开的获取属性值的方法:
① 语法: public 返回值类型 get属性名(){
返回具体属性值的代码
}
② 方法名通常是 get + 属性名首字母大写
getName getAge
③ 返回值类型: 由获取的具体属性值决定
④ 案例: 获取name属性的值
public String getName(){
return this.name;
}
封装后属性如何访问?
// 设置属性值
对象名.set属性名( 具体的值 );
student.setName("tom");
// 获取属性值
对象名.get属性名();
student.getName();
什么是继承?
继承体现的类与类之间的 "is-a"关系
水杯 是一种 容器
钢笔 是一种 笔
狗 是一种 动物
A is-a B
如果 A is-a B 关系成立,则A和B之间存在继承关系;
即:A 继承 B,A称为子类,B称为父类
子类 继承 父类
(2) 语法:
class A extends B{}
A继承B,A是子类,B是父类
(3) 通过继承,子类可以直接使用父类中的属性和成员方法
(4) 注意:继承是类与与之间本身存在的一种is-a关系;
不能为了获取一个类中的属性或是方法而继承另一个类
(5) 子类可以通过继承关系继承父类中的属性和方法;
同时还可以定义自身独有的属性和方法。
注意事项:
a. 子类中定义和父类方法名、参数列表相同的方法,但是返回值类型不同,编译报错
class Animal{
public void eat(){
}
}
class Dog extends Animal{
// 此方法不能覆盖父类中的eat方法,编译报错
public int eat(){
return 0;//
}
}
b. 子类中定义和父类方法名、返回值相同,但是形参列表不同的方法,编译通过,运行结果取决于参数
class Animal{
public void eat(){
}
}
class Dog extends Animal{
// 是特殊的方法重载
public void eat(int n){
}
}
有了继承,子类可以继承父类中哪些内容?
(1) 通过继承关系,子类不能继承父类中构造方法
原因:构造方法的方法名需要和本类的类名一致,子类和父类各有各自的类名;
所以每个类,不管是子类还是父类需要根据自己类名定义本类中的构造方法
(2) 通过继承关系,子类是否能继承父类中属性和成员方法,取决于访问修饰
a. Java中访问修饰符共 4 个
b. 访问修饰符代表的一种访问范围或是权限
访问修饰符 | 本类 | 同包 | 非同包的子类 | 非同包的非子类 |
---|---|---|---|---|
private | √ | |||
default | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
什么是多态?
父类型的引用存储子类型的对象。
多态的语法:
父类类名 引用名 = new 子类类名();
父类型 子类型
引用 对象
注意:父类型的引用可以存储不同类型的子类型对象
(1) 使用父类型的引用调用属性和方法,只能调用父类中有的属性和方法 --> 编译阶段检测
(2) 运行时,jvm自动检测子类有没有覆盖父类中方法;
如果子类覆盖了父类中方法,则优先调用子类覆盖后的方法;
如果没有覆盖则直接调用父类中的方法.
引用之间的转换:
(1) 父类型的引用 赋值给子类型的引用,需要通过强制类型转换
大类型 小类型
a. 语法:
子类类名 引用名 = (子类类名)父类型的引用名;
b. 结果分两种情况:
I. 如果实际存储对象类型和要转换的类型一致,编译通过,运行也通过
Animal a = new Dog();
Dog d = (Dog)a;
II. 如果实际存储对象类型和要转换类型不一致,编译通过,运行报错,错误信息为:
java.lang.ClassCastException; 类型转换异常
Animal a = new Cat();
Dog d = (Dog)a;
(2) 子类型引用 赋值给 父类型的引用 , 可以直接赋值,无需强转 -》体现多态的应用
小类型 大类型
Dog d = new Dog();
Animal a =d; // 体现的多态的应用
(3) 转换双方没有继承关系,不允许强制类型转换,编译报错 -> 转换双方都是 class
Animal a = new Dog();
Person p = (Person)a; // 编译报错,Person和Animal不存在继承关系,没有成功的可能
多态的应用:
(1) 多态应用形式参数上:
如果形参类型为父类型,则所有的子类型都可以作为实参进行传递.
(2) 多态应用在返回值上:
如果返回值类型为父类型,则所有的子类型都可以作为返回值返回.
注意: