0
点赞
收藏
分享

微信扫一扫

面向对象编程3

河南妞 2022-03-11 阅读 54

继承:

小类归于大类,子类归于父类。

类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模。

提高代码的复用性!

extends意思是“扩展”。子类是父类的扩展

不同的叫法:超类、父类、基类  子类、派生类

子类与父类是is-a的关系

为什么使用继承?

使用继承优化后:方便修改代码,减少代码量

如何使用继承?

  1. 编写父类
  2. 编写子类,继承父类

例:class Pet{//公共的属性与方法}

       class Dog extends Pet {//子类特有的属性与方法}

继承关键字:extends,只继承一个父类

Java是单继承关系,一个父类可以有多个子类,但是一个子类只能有一个父类。类似于现实世界中的血缘父子关系。

super关键字:

super是直接父类的引用。

可以通过super来访问父类中被子类覆盖的方法或属性。

普通方法:

       没有顺序限制,可以随便调用。

构造函数中:

       任何类的构造中,若是构造函数的第一行代码没有显式调用super(…);那么

       Java默认都会调用super();作为父类的初始化函数。所以你这里的super();加不加都无所谓。(优先调用父类的构造方法)

理解继承:

使用super关键字,super代表父类的对象

子类访问父类成员

-访问父类的构造方法(在子类构造方法中调用且必须是第一句)

super();

super(name);

-访问父类的属性

super.name;

-访问父类的方法

super.print();

子类可以继承父类的所有资源吗?

不能被继承的父类成员:

  1. 不能直接访问private成员
  2. 子类与父类不在同包,使用默认访问权限的成员
  3. 构造方法

访问修饰符protected可以修饰属性和方法,本类、同类、子类可以访问

多重继承关系的初始化顺序:父类优先与子类

父类属性→父类构造方法→子类属性→子类构造方法

何时使用继承?事物之间符合is-a的关系设计使用继承。继承与真是世界类似:藏獒是一种狗。

继承是代码重用的一种方式。将子类共有的属性和行为放到父类中。

继承小结:

-通过继承可以简化类的定义,实现代码的重用

-子类继承父类的成员变量和成员方法,但不继承父类的构造方法

-Java中只有单继承,没有像C++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。就像我们现实中,如果你有多个父母亲,那是一个多磨混乱的世界啊。多继承,就是为了实现代码的复用性,却引入了复杂性,使得系统之间的关系混乱。

-java中的多继承,可以通过接口来实现

-如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。(顶级父类)

方法的重写(Override)

在子类中可以根据需要对基类中继承来的方法进行重写。

重写方法必须和被重写方法具有相同方法的名称、参数列表和返回类型。

重写方法不能使用比被重写方法更为严格的访问权限。(由于多态)

构造方法不能被继承,因此不能被重写

方法重载小结:

方法重载的规则

-方法名相同

-参数列表相同

-返回值类型相同或者是其子类

-访问权限不能严于子类   

方法重载与重写

位置

方法名

参数表

返回值

访问修饰符

方法重写

子类

相同

相同

相同或是其子类

不能比父类更严格

方法重载

同类

相同

不相同

无关

无关

super继承关键字来访问父类的成员(小结)

-super只能出现在子类的方法和构造方法中

-super调用构造方法时,只能是第一句

-super和this不能同时出现在构造方法中

-super不能访问父类的private成员

-super和this都不能在static方法中

抽象类与抽象方法

抽象类是把相同但不确定的事物提取(抽象)出来,为了以后的具象化重用。(音:chong)

定义成抽象类的目的就是为了在非抽象类的子类中实现抽象类

Java中使用抽象类,限制实例化。因为有的事物的实例化没有意义。

public abstract class Pet{…}

抽象方法:由于有些方法在每个子类的实现不同。

public abstract void print();    //没有具体方法体。

abstract也可用于方法——抽象方法

-抽象方法没有方法体。

-抽象方法必须在抽象类中,抽象类中可以没有抽象方法。

-抽象方法必须在子类中实现,除非子类是抽象类。

final用法

某个类不希望再被其他类继承,使用final类。

方法不希望被重写,使用final方法。

属性值不希望被修改,使用常量。

使用final修饰引用型变量,变量不可以再指向另外的对象。

使用final修饰引用型变量,变量的值是固定不变的,而变量所指向对象的属性值是可变的。

final关键字用法

含义:这是无法改变的 或者 终态的

可以修饰非抽象类、非抽象类成员方法和变量。

可能出于两种理解而需要阻止改变:

设计和效率

  1. final类

final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类的时候,如果这个类不需要子类,类的实现细节不允许改变,并且确信这个类不能被扩展,那么就设计为final类。final方法不能被子类的方法覆盖,但可以被继承。

  1. final方法

如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。

使用final方法的原因有二:

  • 把方法锁定,防止任何继承类修改它的意义和实现。
  • 高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。
  1. final变量(常量)

用final修饰的成员变量表示常量,只能被赋值一次,赋值后值无法改变!

final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。

另外,final变量定义的时候,可以先声明,而不给初值,这种变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象不同而有所不同,却又保持其恒定不变的特征。

  1. final参数

当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。

例:public void fin(final num){}   //num是final类型的,值不允许改变

注:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。

final不能用于修饰构造方法。

Object类

  1. Object类是所有类的父类

一个类如果将没有使用extends显示的继承另外一个类,那么这个类就继承自Object类。

  1. 源码解析(涉及到Object中常用的10个方法)

getClass()、hashCode()、equals(Object)、clone()、toString()、notify()、notifyAll()、wait()、wait(long,int)

finalize()方法为过时的方法或者说是不推荐的方法,主要作用是标识在堆中的对象哪些是没有被引用的,方便JVM中的GC进行垃圾回收。

3、对象的比较“==”与equals()

a.==:

(1)比较两基本类型变量的值是否相等

(2)比较两个引用类型的值即地址是否相等,即是否指向同一个对象。

b.equals():

(1)比较地址(对象)是否相同

(2)比较两对象的内容是否相同

c:自定义类须重写equals(),否则其对象比较结果总是false。

 通过阅读API帮助文档Object源码可知,equals()方法的实现是用“==”完成的

      即,在Object中,==与equals()没有区别,

但是,在String类中,String类对Object中的equals()方法和HashCode()算法  进行了重写。

-equals()方法将此字符串与指定的对象比较。当且仅当该参数不为null,并且是

           与此对象表示相同字符序列的String对象时,结果才为true。(比较的是对象的    值)

Java是一种单继承语言,也就是说,Java中所有的类都有一个共同的祖先,就是Object类,即使没有显示声明,编译器也会默认加上。该类有12个成员方法,分别是clone():Object、equals(Object):boolen、finallize():void、getClass()、hashCode():int、notify():void、notifyAll():void、toString():String、wait():void、wait(long):void、wait(long,int):void

getClass():返回某个对象在运行时的类型(被实例化的类),匿名内部类返回形式为系统自动生成的代码

clone():另存一个当前存在的对象

equals():判断两对象是否相等

hashCode():对象签名。该方法用来返回其所在对象的物理地址(哈希码值),常会和equals()方法同时重写,确保相等的两个对象拥有相等的.hashcode。

toString():1.一般来说通过重写该方法,返回一个String对象,用来标识自己(输出需要的那部分)。2.该方法在打印对象时被调用,将信息变为字符串返回,默认输出对象地址。

关于多线程机制:wait():void、wait(long):void、wait(long,int):void、notify():void、  notifyAll():void

关于垃圾回收:finalize()

继承深化

父类方法的重写:

“==”:方法名、形参列表相同。

“≤≤”:返回值类型和异常类型,子类小于父类。

“≥”:访问权限,子类大于等于父类。

构造方法调用顺序:

-根据super的说明,构造方法第一句总是:super(…)来调用父类对应的构造方法。

-先向上追溯到Object,然后依次向下执行类的初始化块和构造方法,直到当前子类为止.

关于代码实现:

  1. 发现类
  2. 发现类的属性
  3. 发现类的方法
  4. 优化设计:可以抽取父类或者检查abstract,final之类的

5、编写程序入口(编写测试代码运行)

梳理运行过程:1、实例化类的对象

                          2、调用方法实现业务等

举报

相关推荐

0 条评论