Java自学 --换车重启9

继承

​ 继承可以解决代码复用,让我们的编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过 extends来声明继承父类即可。

class 子类 extends 父类{
    
}
//自乐你自动拥有父类定义的属性和方法
//父类又叫超类、基类
//子类又叫派生类

继承 — 细节

  • 子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问

  • 子类没有继承父类的构造器,但必须调用父类的构造器, 完成父类的初始化

  • 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过(怎么理解。) [举例说明]

  • 如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)

  • super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)

  • super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器

  • java 所有类都是 Object 类的子类, Object 是所有类的基类.

  • 父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类)

  • 子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。

    • 思考:如何让 A 类继承 B 类和 C 类? 【A 继承 B, B 继承 C】
  • 不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系


super

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

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

​ super 的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用 super 去访问爷爷类的成员

​ 上面这句话个人的理解是,跳过本类(即便本类有也不看),逐级往上查找,查到有为止,如果有不能访问就报没权限,如果没有就说找不到。


调用父类方法或属性的查找规则

public class B extends A {
	public void sum() { 
        //希望调用父类-A 的 cal 方法
        //3种查找方法
        cal();
        this.cal();  //和第一个cal();等价
        super.cal(); //跳过本类直接查找上一级父类,其他规则一样
        //找 cal 方法时(cal() 和 this.cal()),顺序是: 
        // (1)先找本类,如果有,则调用 
        // (2)如果没有,则找父类(如果有,并可以调用,则调用) 
        // (3)如果父类没有,则继续找父类的父类,整个规则,就是一样的,直到 Object 类 
        // 提示:如果查找方法的过程中,找到了,但是不能访问(private), 则报错, cannot access
        // 提示:如果查找方法的过程中,没有找到,则提示方法不存在
        
    }    
}    
---------------------------------------------------------------
   		 //查找属性的方法同上

super 细节

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

super 和 this

区别thissuper
1访问属性访问本类中的属性,如果本类没有此属性则从父类中继续查找从父类开始查找属性
2调用方法访问本类中的方法,如果本类没有此方法则从父类继续查找从父类开始查找方法
3调用构造器调用本类构造器,必须放在构造器的首行调用父类构造器,必须放在子类构造器的首行
4特殊表示当前对象子类中访问父类对象

方法重写

方法重写也叫方法覆盖,需要满足下面的条件

  • 子类的方法的形参列表,方法名称,要和父类方法的形参列表,方法名称完全一样
  • 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类
比如父类返回类型是Object, 子类方法返回类型是String【演示】
    public Object get Info(){}
	public String get Info(){}
  • 子类方法不能缩小父类方法的访问权限
	void say Ok() {}
	public void say Ok() {}

重写和重载的区别

重载(overload)重写(override)
发生范围本类中子类父类中
方法名必须一致必须一致
参数列表必需不一样(类型,个数或者顺序至少有一个不同)一致
返回类型可以不一样(无要求)和父类一致,或是返回父类的子类
修饰符无要求可以一样或者扩大范围,但是不能缩小

多态(重点难点)

​ 方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。

  • 方法的多态:重写和重载就体现多态
  • 对象的多态 (核心,困难,重点):
    • 一个对象的编译类型和运行类型可以不一致
    • 编译类型在定义对象时,就确定了,不能改变
    • 运行类型是可以变化的
    • 编译类型看定义时=号的左边,运行类型看=号的右边
Animal animal = new Dog();  
//animal编译类型是Animal,运行类型Dog
animal = new Cat();  
//animal的运行类型变成了Cat,编译类型仍是Animal

多态细节(向上转型)

​ 多态的前提是:两个对象(类)存在继承关系

//向上转型调用方法的规则如下: 
//(1)可以调用父类中的所有成员(需遵守访问权限) 
//(2)但是不能调用子类的特有的成员 
//(3)因为在编译阶段,能调用哪些成员,是由编译类型来决定的 //animal.catchMouse();错误 
//(4)最终运行效果看子类(运行类型)的具体实现, 即调用方法时,按照从子类(运行类型)开始查找方法 
//,然后调用,规则我前面我们讲的方法调用规则一致。

多态细节(向下转型)

//语法:子类类型  引用名 =  (子类类型)父类引用;
//只能强转父类的引用,不能强转父类的对象
//要求父类的引用必须指向的是当前目标类型的对象
//当向下转型后,可以调用子类类型中所有的成员
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值