文章目录
封装
概念
-
尽可能隐藏对象的内部实现细节,控制对象的修改及访问的权限
-
将一个事物进行包装,提供对外使用的方法
-
访问修饰符:private (可将属性修饰为私有,仅本类可见)
公共的访问方法
public class TestEncapsulation{
public static void main(String[] args){
Student s1 = new Student();
s1.setAge(20); //以访问方法的形式,进而完成赋值与取值操作。
//问题:依旧没有解决到非法数据录入
System.out.println(s1.getAge());
}
}
class student{
String name;
private int age;
String sex;
double score;
/*提供公共访问方法,以保证数据的正常录入
命名规范:
赋值:setXXX() //使用方法参数实现赋值
取值:getXXX() //使用方法返回值实现取值
*/
public void setAge(int age){
this.age = age;
}
public void getAge(){
return age;
}
}
过滤有效数据
在公共的访问方法内部,添加逻辑判断,进而过滤掉非法数据,以保证数据安全
以上面代码的age变量为例:
public void setAge(int age){
if(age > 0 && age <= 100 ){//指定有效范围
this.age = age;
}else{
this.age = 18; //录入非法数据时的默认值
}
}
public void getAge(){
return this.age;
}
好处
- 保护内部(get/set方法是外界访问对象私有属性的唯一通道,方法内部可对数据进行检测和过滤)
- 方便使用
- 降低耦合度
继承
思想
- 真实世界的继承——获得长辈存留的事物
- 程序中的继承——是类与类之间特征和行为的一种赠与或获得(两个类之间的继承关系,必须满足"is a "的关系
Dog is an Animal. 成立
Cat is an Animal. 成立
继承语法 、应用、好处
使用方法:
访问权限修饰符 class 子类 extends 父类 {
}//定义子类时,显示继承父类
**应用:**产生继承关系后,子类可以使用父类中的属性和方法,也可定义子类独有的属性和方法。
**好处:**既能提高代码的复用性,又能提高代码的可扩展性。
继承特点
- 子类拥有父类所有属性与方法
- 子类只能拥有一个直接父类,但是可以多级继承,属性和方法逐级增加
访问权限修饰符
- public : 当前项目中皆可使用
- protected : 同一个包中或继承关系中可以使用
- 默认的: 同一个包中可以使用
- private : 只能在当前类中使用
如下表所示:
本类 | 同包 | 非同包子类 | 同项目 | |
---|---|---|---|---|
private | √ | × | × | × |
default(默认的) | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ | √ |
不可使用(继承)
- 构造函数
- 类中的构造方法,只负责创建本类对象,不可继承。
- 使用private修饰的方法或属性不能直接使用
- 访问修饰符的一种,仅本类可见
- 在不同包中不可使用默认权限修饰符修饰的方法或属性不能直接使用
- 访问修饰符的一种,仅同包可见。
继承后对象创建过程
- 开辟内存空间
- 加载父类
- 加载子类
- 调用父类构造函数
- 调用子类构造函数
- 赋值给变量
重写与重载
重写
方法重写原则
- 在继承关系中,子类方法与父类方法
- 访问权限修饰符只能变大或不变,不能缩小
- 返回值类型相同
- 方法名相同
- 形参列表相同
方法重写的执行
- 子类重写父类方法后,调用时优先执行子类重写后的方法。
方法重载的概念
- 有些情况下,对象的同一种行为可能存在多种实现过程
- 重载(Overload):一个类中定义多个相同名称的方法
- 要求:
- 方法名称相同
- 参数列表不同(类型 、 个数、 顺序)
- 与访问修饰符、返回值类型无关
- 调用带有重载的方法时,需要根据传入的实参去找到与之匹配的方法
- 好处:屏蔽使用差异,灵活、方便
super关键字与this关键字
super的用法
- 调用父类构造函数
- 调用父类的方法
this
- 调用本类构造函数
- 调用本类方法
- 调用本类属性
- 区分成员变量与局部变量
多态
概念
生活中的多态
- 生活中的多态是指”客观事物在人脑中的主观反应“
- 主观意识上的类别与客观存在的对象具有” is a“关系时,即形成多态
程序中的多态
-
概念:父类引用指向子类对象,从而产生多种形态。
//父类引用(引用类型)Animal a = new Dog();//子类对象(对象类型)
-
二者具有直接或间接的继承关系时,父类引用可指向子类对象,即形成多态
-
父类引用仅可调节父类所声明的属性和方法,不可调用子类独有的属性和方法
多态的应用
应用场景
- 场景一:
- 使用父类作为方法形参实现多态,使方法的参数类型更为宽泛
- 场景二:
- 使用父类作为方法返回值实现多态,使方法可以返回不同的子类对象
向上转型(装箱)
public class TestConvert{
public static void main(String[] args){
Animal a = new Dog(); //父类引用中保存真实子类对象,称为向上转型(即多态核心概念)
}
}
//注意:仅可调用Animal中所声明的属性和方法
class Animal{
public void eat(){
System.out.println("动物在吃。。。");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗在吃骨头。。。");
}
}
向上转型(拆箱)
public class TestConvert{
public static void main(String[] args){
Animal a = new Dog();
Dog dog =(Dog)a;//将父类引用中的真实子类对象,强转回子类本身类型,称为向下转型
}
}
//注意:只有转换回子类真实类型,才可调用子类独有的属性和方法
class Animal{
public void eat(){
System.out.println("动物在吃。。。");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗在吃骨头。。。");
}
}
类型转换异常
public class TestConvert{
public static void main(String[] args){
Animal a = new Dog();
Cat cat =(Cat)a;
/**
会报java.lang.ClassCastException异常
向下转型时,如果父类引用中的子类对象类型与转型对象不匹配,则会发生类型转换异常
/
}
}
class Animal{
public void eat(){
System.out.println("动物在吃。。。");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗在吃骨头。。。");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫在吃鱼。。。");
}
}
instanceof关键字
- 向下转型前,应判断引用中的对象真实类型,保证类型转换的正确性
- 语法:
父类引用 instanceof 类型 //返回boolean类型结果
- 语法:
以上面的程序为例:
if(a instanceof Dog){
Dog dog = (Dog)a;
dog.eat(); //当"a"引用中存储的对象类型确实为Dog时,在进行类型转换,进而调用Dog中的独有方法。
}else if(a instanceof Cat){
Cat cat = (Cat)a;
cat.eat();
}
//运行结果为:狗在吃骨头。。。
总结
- 多态的两种应用场景:
- 使用父类作为方法形参,实现多态
- 调用方法时,可传递的实参类型包括:本类型对象+其所有的子类对象。
- 使用父类作为方法返回值,实现多态
- 调用方法后,可得到的结果类型包括:被类型对象+其所有的子类对象
- 使用父类作为方法形参,实现多态
- 多态的作用
- 屏蔽子类之间的差异
- 灵活、耦合度低