第三章:面向对象编程(进阶)
第七章:面向对象编程(进阶)
1.目前可能出现的问题?及解决方案?
为我们在声明一个属性对应的setXxx方法时候,通过形参给对应的属性赋值。如果形参名跟属性名同名了,如何区分两个变量?
解决方案:使用this。具体来讲,使用this的变量,表示的是属性,没有this的表示的是形参
2.this可以调用的结构:成员变量、方法、构造器
3.this的理解:当前对象(方法调用中) 或 当前正在创建的对象(构造器调用时)
4.1 this调用属性和方法
针对于方法内的使用情况:(非static修饰的方法)
一般情况:我们通过对象调用方法,可以再方法内调用当前对象的属性或其他方法。此时,我们可以在属性和方法前使用“this”,表示当前属性或方法所属的对象。一般情况下会省流this
特殊情况:方法的形参和对象的属性同名,要用this区分
针对于构造器内的使用情况:(与方法内使用情况差不多)
4.2 this调用构造器
>格式:“this(形参列表)”
>我们在类的构造器中,调用当前类中指定的其他构造器
>要求:“this(形参列表)”必须声明在当前构造器的首行
>结论:构造器里面调用this只能用一次

- 生活上:财产的继承、研制的继承
- 代码层面:
- 自上而下:定义了一个类A,在定义另一个类B时,发现B的功能与A类似,考虑B继承A
- 自下而上:定义了BCD等,发现BCD有类似的属性和方法,考虑把这些相同的抽取封装到A中,再让BCD继承A
- 减少了代码的冗余,提高复用性
- 有利于功能扩展
- 让类与类之间产生了“is-a”的关系,为多态的使用提供了前提
- 父类更通用,更一般,子类更具体
Plain Text |
继承中的基本概念:
类A:父类、superClass、超类
类B:子类、subClass、派生类
- 子类就获取到了父类中声明的所有的属性和方法。
- 但是,由于封装性的影响,可能子类不能直接调用父类中声明的属性或方法。
- 子类在继承父类后,还可以扩展自己特有的功能
- 不要为了继承而继承
java中声明的类,如果没有显示的声明其父类时,则默认继承于java.long.Object
- 一个父类可以有多个子类
- java只支持单继承,一个子类只能有一个父类
子类在继承父类以后,获取了父类中声明的所有方法。但是有些时候这些方法不太使用。所以需要进行一个覆盖,重写。
距离(银行账户):
Plain Text |
子类对父类继承过来的方法进行覆盖、覆写的行为,叫做重写
方法声明的格式:权限修饰符 返回值类型 方法名 [throws 异常类型](形参列表){方法体}
具体规则:
①父类被重写的方法与子类重写的方法名和形参列表必须相同(有重构)
②子类重写的方法的权限修饰符>=父类的
>如果父类里面是private,子类不能重写
③返回值类型:
>父类被重写的方法的返回值类型是void,则子类也必须是void
>父类被重写的方法的返回值类型是基本数据类型,则子类也必须相同
>父类被重写的方法的返回值类型是引用数据类型(比如类),子类重写的方法的返回值类型可以相同,或者是它的子类(不能是父类)
④(现阶段超纲):子类重写的方法抛出的异常类型可以与父类的异常类型相同,或者是父类被重写的方法抛出的异常类型的子类
重载:“两同一不同”
重写:继承以后,子类覆盖父类同名同参的方法
[类比]相同类型的面试题:
throws/throw
Final / finally /finalize
Collection / Collections
String /StringBuffer/StringBuilder
ArrayList/LinkedList
举例1:子类继承父类以后,对父类的方法进行了重写,那么在子类中,是否还可以对父类中被重写的方法进行调用?
举例2:子类继承父类以后,发现子类和父类中定义了同名的属性,是否可以在子类中区分两个同名的属性
如何调用?使用super关键字
具体的
3.1super调用属性方法
子类继承父类以后,我们可以再子类的方法或者构造器中,调用父类中声明的属性或方法。(满足封装性的前提下)
调用时,需要使用"super."
3.2 super调用构造器
①子类继承父类时,不会继承父类的构造器。只能通过”super(形参列表)“的方式调用
②”super(形参列表)“的方式调用必须声明在构造器首行
③构造器的首行可以使用“this(形参列表)”,调用本类中重载的构造器,而结论二也是首行,所以两个只能二选一
④两个都没有调用,默认调用super()
⑤子类的任何一个构造器,要么调用本类中重载的构造器,要么调用父类的构造器
代码举例:
Plain Text |
1.从结果的角度来看:体现为类的继承性
当我们创建子类对象后,子类对象就获取了其父类中声明的所有属性和方法,在权限允许的情况下,可以直接调用
2.从过程的角度来看:
当我们通过子类的构造器创建对象时,子类的构造器一定会直接或者间接的调用到父类的构造器,而父类的同样会调用到它的父类的构造器...直到调用到Object构造器为止
3.问题:在创建子类对象的时候,到底有几个对象?
只有一个
理解:一个事物的多种形态
生活举例:
>女朋友:我想养一个宠物。
>孩子:我想要一个玩具。
>老板:安排一个技术科同事,下周出差。
子类对象的多态性:父类的引用指向子类的对象
比如Person p = new Man();
多态性的引用:虚拟方法调用
在多态的场景下,调用方法时。
编译时,认为方法是左边声明的父类的类型
执行时,实际执行的是子类重写父类的方法
简称为:编译看左边,运行看右边

①要有类的继承关系
②要有方法的重写
适用于方法,不适用于属性
好处:
减少代码的冗余,不如要定义多个重载的方法
弊端:
在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法,但是你声明的是父类,所以不能直接调用子类特有的属性和方法
考虑上述问题,如何调用子类特有的属性和方法,采用转型的方法,比如

转型可能会出现的问题

如何解决?采用instanceof判断

/*
1.建议在向下转型之前,使用instanceof进行判断,避免出现类型转换异常
2.格式: a instanceof A :判断对象a是否是类A的实例
3.如果a instanceof A 返回true,则:
a instanceOf superA 返回的也是true。其中A 是 superA的子类
*/

明确:java.long.Object
任何一个Java类(除了Object)都直接或间接的继承于Object类
Object类称为java类的根父类
Object类中声明的结构(属性,方法)就具有通用性
t没有声明属性
提用了一个空参的构造器
重点关注:方法
重点方法:equals() \ toString()
了解方法: clone() \ finaliza()
目前不需要关注getClass() \hashCode() \
任何引用数据类型都可以使用。
Plain Text |
- 自定义的类在没有重写equals()方法的情况下,调用的就是Object中的方法,比较两个对象引用地址是否相同。
- 对于像String、File、Date和包装类等,他们都重写了Object类中的equals()方法,用于比较两个对象的实体内容是否相等
- 实际开发中,针对于自定义的类,常常会判断两个对象是否相等,而此时主要是判断属性值是否相等,此时就需要重写equals()
- 如何重写?
- 手写
- IEDA alt+insert自动写
==:就是一个运算符
①适用范围:基本数据类型、引用数据类型
②基本数据类型:判断数据值是否相等
③引用数据类型:比较地址值是否相等
equals():方法
①适用范围:引用数据类型
②具体使用:对于类来说,重写和不重写的区别(比较地址值还是属性)
4.1定义
Plain Text |
4.2开发中的使用场景
- 平时我们用System.out.println()打印对象引用变量时,其实调用了对象的toString()
4.3 子类使用说明:
- 自定义类:没有重写,返回默认地址值
- 像String、File、Date或包装类,他们都重写了方法,在调用时返回当前对象的实体内容
4.4 开发中使用说明:
- 习惯上,开发中对于自定义的类在调用toString()时,也希望显示对象的实体内容,而不是地址值
浙公网安备 33010602011771号