javase(2023/11/12)

目录

1、封装

2、继承

3、super关键字

 4、方法重写/覆盖(override)

5、多态


1、封装

好处

  • 隐藏实现细节:方法(连接数据库)<--调用(传入参数..)
  • 可以对数据进行验证,保证安全合理

2、继承

好处

  • 代码的复用性提高了
  • 代码的扩展性和维护性提高了

注意事项

  1. 子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访 问,要通过父类提供公共的方法去访问
  2. 子类必须调用父类的构造器, 完成父类的初始化
  3. 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器(不管有无参,默认调用的都是父类的无参构造器) ,如果父类没有提供无 参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译错误
  4. 如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)
  5. super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)
  6. super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器(当有this时,默认的super也没有,默认的super会出现在this方法所代表的构造器内)
  7. java 所有类都是 Object 类的子类, Object 是所有类的基类.
  8. 父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类),即可能创建一个对象会调用多个构造器
  9. 子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。 
  10. 不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系

本质分析

 

Son son = new Son();//内存的布局
//?-> 要按照查找关系来返回信息
//(1) 首先看子类是否有该属性

//(2) 如果子类有这个属性,并且可以访问,则返回信息,
//不可以访问则报错(比如private,即使再往上查找有公有的这个属性)

//(3) 如果子类没有这个属性,就看父类有没有这个属性
//(如果父类有该属性,并且可以访问,就返回信息..)

//(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到 Object... 

System.out.println(son.name);//返回就是大头儿子
//System.out.println(son.age);//返回的就是 39
//System.out.println(son.getAge());//返回的就是 39
System.out.println(son.hobby);//返回的就是旅游

若要调用Father和Grandpa类中的name,创建 Father和Grandpa对象

3、super关键字

super 代表父类的引用,用于访问父类的属性、方法、构造器

基本语法

  • 访问父类的属性,但不能访问父类的private属性[案例]super.属性名;
  • 访问父类的方法,不能访问父类的private方法super.方法名(参数列表);
  • 访问父类的构造器:super(参数列表);只能放在构造器的第一句,只能出现一句!
     

好处

  • 调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子类初始化)
  • 当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果
  • super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。A->B->C,当然也需要遵守访问权限的相关规则。总的来说就是访问最近的上一级成员

 4、方法重写/覆盖(override)

方法覆盖(重写)就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法

重写和重载的比较

5、多态

引入

基本介绍

  • 多态的前提是:两个对象(类)存在继承关系
  • 方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。

具体体现1(方法的多态,重写和重载就体现多态)

//方法重载体现多态
A a = new A();
//这里我们传入不同的参数,就会调用不同 sum 方法,就体现多态
System.out.println(a.sum(10, 20));
System.out.println(a.sum(10, 20, 30));
//方法重写体现多态
B b = new B();
a.say();
b.say();

编译类型和运行类型

  • 一个对象的编译类型和运行类型可以不一致
  • 编译类型在定义对象时,就确定了,不能改变
  • 运行类型是可以变化的
  • 编译类型看定义时=号的左边,运行类型看=号的右边
     
//animal编译类型是Animal,运行类型Dog
Animal animal = new Dog0; 

//animal的运行类型变成了Cat,编译类型仍然是 Animal
animal = new Cat();


 具体体现2(对象的多态,上下转型) 

多态向上转型

  • 本质:父类的引用指向了子类的对象(把子类赋给了父类),这里父类包括父类的父类及更高
  • 语法:父类类型 引用名=new 子类类型()
  • 特点:编译类型看左边,运行类型看右边。
  • 可以调用父类中的所有成员(需遵守访问权限),不能调用子类中特有成员
  • 最终运行效果看子类的具体实现!
//向上转型: 父类的引用指向了子类的对象
//语法:父类类型引用名 = new 子类类型();
Animal animal = new Cat();
Object obj = new Cat();//可以吗? 可以 Object 也是 Cat 的父类

//向上转型调用方法的规则如下:
//(1)可以调用父类中的所有成员(需遵守访问权限)
//(2)但是不能调用子类的特有的成员
//(#)因为在编译阶段,能调用哪些成员,是由编译类型来决定的
//animal.catchMouse();Cat的特有方法,会报错
//(4)最终运行效果看子类(运行类型)的具体实现, 即调用方法时,按照从子类(运行类型)开始查找方法
//,然后调用,规则和方法调用规则一致。
animal.eat();//猫吃鱼,Cat类重写的方法
animal.run();//跑,父类的方法
animal.show();//hello,父类的方法
animal.sleep();//睡,父类的方法

多态向下转型

  • 语法:子类类型 引用名=(子类类型)父类引用
  • 只能强转父类的引用,不能强转父类的对象
  • 要求父类的引用必须指向的是当前目标类型的对象
  • 当向下转型后,可以调用子类类型中所有的成员
//多态的向下转型
//(1)语法:子类类型 引用名 =(子类类型)父类引用;
//编译类型 Cat,运行类型是 Cat
Cat cat = (Cat) animal;
cat.catchMouse();//猫抓老鼠

//(2)要求父类的引用必须指向的是当前目标类型的对象
//即原来的anminal指向Cat类型
Dog dog = (Dog) animal; //不可以

 属性的值看编译类型

public class PolyDetail02 {
    public static void main(String[] args) {
    //属性没有重写之说!属性的值看编译类型
    Base base = new Sub();//向上转型
    System.out.println(base.count);// ? 看编译类型 10
    Sub sub = new Sub();
    System.out.println(sub.count);//? 20
    }
}

class Base { //父类
    int count = 10;//属性
}

class Sub extends Base {//子类
    int count = 20;//属性
}

instanceOf 比较操作符,用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型

public class PolyDetail03 {
    public static void main(String[] args) {
        BB bb = new BB();
        System.out.println(bb instanceof BB);// true
        System.out.println(bb instanceof AA);// true
        
        //aa 编译类型 AA, 运行类型是 BB
        //BB 是 AA 子类
        AA aa = new BB();
        System.out.println(aa instanceof AA);
        System.out.println(aa instanceof BB);
        Object obj = new Object();
        System.out.println(obj instanceof AA);//false
        String str = "hello";
        //System.out.println(str instanceof AA);
        System.out.println(str instanceof Object);//true
    }
}
class AA {} //父类
class BB extends AA {}//子

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值