封装
1. 封装的作用和意义
- 面向对象的三个基本特征:封装、继承、多态
- 封装的定义:
- 把对象的属性和操作结合为一个独立的整体,尽可能隐藏对象的内部实现细节。
- 程序设计追求“高聚合,低耦合”。(把复杂性封装起来,用的时候尽可能的简单)
- 高聚合:就是类的内部数据操作细节自己完成,不允许干涉。
- 低聚合:是仅暴露少量的方法外部使用,尽量方便外部调用。
2. 封装的优点
- 提高代码的安全性
- 提高代码的复用性
- “高内聚”:封装细节,便于修改内部代码,提高可维护性
- “低耦合”:简化外部调用,便于调用者使用,便于扩展和写作。
3. 封装的细节
- 属性的私有化
- 提供公开的 get、set 方法
- 一般使用 private 访问权限修饰来修饰成员变量
- 提供相应的 get、set 方法来访问相关属性,这些方法通常是 public 修饰的。以提供对属性的赋值与读取操作
- 一些只用于本类的辅助性方法,可以使用 private 修饰
- 希望其他类调用的方法用 public 修饰。
继承
1. 继承的概念及意义
- 继承概念:
- 所谓继承是指一个类的定义可以基于另外一个已经存在的类,即子类基于父类,从而实现父类代码的重用,子类能吸收已有类的数据属性和行为,并能扩展新的能力。
- 继承的意义:
- 通过使用继承我们能够非常方便地复用以前的代码,能够大大的提高开发的效率。
2. 继承的声明形式
3. 继承的优点
- 提高了代码的复用性
- 提高了代码的维护性
- 让类与类之间产生了关系,是多态的前提
4. 继承的特点以及注意事项
5. 继承中成员变量的关系
- 在子类方法中访问一个变量
- 首先在子类局部范围找
- 然后在子类成员范围找
- 最后在父类成员范围找(肯定不能访问到父类局部范围)
- 如果还是没有就报错。(不考虑父亲的父亲…)
6. super 关键字
- super(…)或者this(…)必须出现在第一条语句上
7. 继承中构造方法的关系
- 子类中所有的构造方法默认都会访问父类中无参数的构造方法
- 为什么呢?
- 因为子类会继承父类中的数据,可能还会使用父类的数据。子类初始化之前,一定要先完成父类数据的初始化。
- 每一个构造方法的第一条语句默认都是:super()
- 如果父类中没有构造方法,该怎么办呢?
- 子类通过 super 去显示调用父类其他的带参的构造方法
- 子类通过 this 去调用本类的其他构造方法:本类其他构造也必须首先访问了父类构造
8. 继承中成员方法的关系
- 在子类方法中访问一个方法
- 首先在子类局部范围找
- 然后在子类成员范围找
- 如果还是没有就报错。(不考虑父亲的父亲…)
9. 方法覆盖(重写)
- 定义:
- 子类可以重写父类中某一个方法,称为方法覆盖,也称方法重写,是继承中非常重要的知识点。如果子类需要修改从父类继承到的方法的方法体,就可以使用方法覆盖
- 方法覆盖的原则
多态
0. 引子
1. 多态概念
- 面向对象的三个基本特征:封装、继承、多态
- 多态的含义是:对外的一种表现形式,内在具有多种具体实现。
- java 中多态的具体体现
2. 方法的重载
-
方法重载的概念
-
方法重载的三大原则
- 方法名相同
- 参数不同(数量不同、类型不同、顺序不同)
- 同一作用域
- 注意:方法重载跟方法的返回值类型没有任何关系,只有返回值不同的方法不能构成重载。请勿将功能完全不一样的方法进行重载!
-
方法重载的好处
3. 向上造型
- 向上造型—自动类型提升
- 定义:子类类型自动转换为父类类型,不需要强转.父类型的引用指向子类对象,对象向上造型也叫自动类型提升
- 作用:提高程序可拓展性
- 对象dog 可以调用狗类中所有的方法(包括宠物类中所有非私有方法)
- p 只能调用宠物类中定义的方法,狗类扩展的新方法不能调用
4. 多态环境下对属性和方法的调用
1. 多态环境下对非静态方法的调用
父类型 变量名=new 子类型();
public class Pet {
public void m1(){
System.out.println("这是Pet的m1()方法");
}
public void toHostpital(){
System.out.println("宠物看病");
}
}
public class Dog extends Pet {
public void toHostpital(){
System.out.println("狗看病");
}
public void shout(){
System.out.println("Dog.shout()方法");
}
}
public class MasterTest {
public static void main(String[] args) {
Pet p=new Dog();
p.m1();
p.toHostpital();
}
}
2. 多态性的情况下对静态成员方法的调用
public class Pet {
public void m1(){
System.out.println("这是Pet的m1()方法");
}
public void toHostpital(){
System.out.println("宠物看病");
}
public static void m2(){
System.out.println("Pet.m2()static方法");
}
}
public class Dog extends Pet {
public void toHostpital(){
System.out.println("狗看病");
}
public void shout(){
System.out.println("Dog.shout()方法");
}
public static void m2(){
System.out.println("Dog.m2()static方法");
}
}
public class MasterTest {
public static void main(String[] args) {
Pet pet =new Dog();
pet.m2();
}
}
3. 成员变量
- 对成员变量的调用:编译运行都看左边。
- 注意:变量不存在被子类覆写这一说法,只有方法存在覆写。
所以,静态变量也是编译和运行都看等号左边。
class Pet{
int num = 3;
}
class Dog extends Pet{
int num = 4;
}
Pet pet = new Dog()
System.out.println( pet.num ) ;
4. 结论
- 编译期和运行期相同的情况:A a = new A();
- 编译期和运行期不同的情况
- 父类和子类有相同的成员变量(静态和非静态),多态下访问的是父类的成员变量。
- 当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的是子类的成员方法。
- 当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问的是父类的静态方法
5. 多态参数
-
定义:方法的形式参数类型是父类类型,而传递的实际参数可以是该父类任意子类的对象 -
方法参数多态性的好处:提高代码的扩展性
总结
? 1.多态:一种行为,有多种不同形式的表现 ? 2.多态的具体体现 ? 1.方法重载 ? 2.方法覆盖 ? 3.多态参数 ? 3.方法重载:同一个类中有多个同名的方法,但是参数不同(参数的类型不同,参数的顺序不同,参数的个数不同),叫做方法的重载 ? 4.对象向上造型:子类类型自动转换为父类类型,不需要强转 ? 5.多态环境下对属性和方法的调用 ? 1)多态环境下对非静态方法的调用 ? 父类型 变量名=new 子类型(); ? pet对象: 编译看左边 ,运行看右边 ? 2)多态性的情况下对静态成员方法的调用 ? 对静态成员方法的调用:编译运行都看左边 ? 3)多态性的情况下对非静态成员变量,静态成员变量的调用 ? 对非静态,静态成员方法的调用:编译运行都看左边 ? 换言之: ? 编译期和运行期不同的情况; ? ? 父类和子类有相同的成员变量(静态和非静态),多态下访问的是父类的成员变量。 ? ? 当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的 ? 是子类的成员方法。 ? ? 当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问 ? 的是父类的静态方法 ? 6.多态参数:方法的形式参数类型是父类类型,而传递的实际参数可以是该父类任意子类的对象 ? 7.多态作为返回值类型:返回值是父类型的引用,方法体的return返回的是子类对象
6. 多态的前提与弊端
- 多态的前提:类之间有关系:继承或者实现
- 多态的弊端:只能调用父类的方法,不能调用子类特有的方法
7. 对象向下造型
-
定义:父类型引用转换为子类型 -
公式:子类型 变量名=(子类型)父类型变量名 -
作用:为了使用子类中特有的方法 Dog d=(Dog)p;
d.shout();
8. 多态的注意事项
-
不能把父类向下转换为子类类型 Pet pet=new Pet(); Dog dog=(Dog)pet; -
不具备继承关系的类不能互转 Pet p=new Cat();
Dog d=(Dog)p;
-
对于转型,只能强制转换成这个对象的运行期类型 Pet p=new Dog();
Dog d=(Dog)p;
总结
1. 多态转型:
- 向上造型(自动)
- 向下造型(强制)
2. 多态向上转型的特点:
- 限制了对子类特有方法的访问,提高代码的扩展性
3. 多态向下转型的特点:
- 为了使用子类特有方法
9. instanceof 运算符
- 作用:运算符 instanceof 用来判断对象是否属于某个类的实例
- 公式:对象名 instanceof 类名
该表达式为一个boolean表达式,如果对象的类型是后面提供的类或其子类,则返回true,反之返回false - 案例:
1.Animal eat() 1.Dog:eat() lookingHome() 2.Cat:eat() catchMouse() 2.AnimalTest 判断Dog类型或者Cat类型
public class Animal {
public void eat(){
System.out.println("动物吃饭");
}
}
package t01;
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗啃骨头");
}
public void lookingHome(){
System.out.println("狗看家");
}
}
package t01;
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
package t01;
public class AnimalTest {
public static void main(String[] args) {
Animal animal=new Cat();
animal.eat();
if (animal instanceof Dog){
Dog dog= (Dog) animal;
dog.lookingHome();
}
if (animal instanceof Cat){
Cat cat= (Cat) animal;
cat.catchMouse();
}
}
}
|