04_Java面向对象特征之继承与多态
1. 继承
Java继承的实现(只支持单继承,而不是多继承,但有接口的多实现)
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类. 定义类时直接通过extends关键字指明要继承的父类.子类对象除了可以访问子类中直接定义的成员外,也可访问父类的所有非私有成员.能否直接访问父类私有成员则取决于访问权限设置.
继承的作用:(注意:不要仅为了获取其他类中某个功能而去继承, 类与类之间要有所属( " is a " )关系)
继承提高了代码的复用性。
继承的出现让类与类之间产生了关系,提供了多态的前提。
如何使用一个继承体系中的功能:
查阅父类功能(定义了共性的功能)
创建子类对象使用功能(因为父类可能不能创建对象, 而且子类提供了更丰富的功能)
继承中自子类变量的特点:
如果子类出现非私有的同名变量时, 子类访问本类变量用this, 子类访问父类中的同名变量用super.
继承中函数的特点:
函数覆盖(Override)
子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为重写或者复写。
父类中的私有方法不可以被覆盖。
在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取。
覆盖注意事项:
• 覆盖时,子类方法权限一定要大于等于父类方法权限
• 静态只能覆盖静态。
覆盖的应用:
• 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内
构造方法在类继承中的作用
构造方法不能继承.由于子类对象要对来自父类的成员进行初始化,因此,在创建子类对象时除了执行子类的构造方法外,还需要调用父类的构造方法.具体遵循如下原则:
(1) 当子类未定义构造方法时,创建对象时将无条件地调用父类的空构造方法,以为每行第一条super();
(2) 对于父类的含参数构造方法,子类可以在自己构造方法中使用关键字super来调用它,但super调用语句必须是子类构造方法中的第一个可执行语句;
(3) 子类在自己定义构造方法中如果没有用super明确调用父类的构造方法,则在创建对象时,将自动先执行父类的无参构造方法,然后再执行自己定义的构造方法。
所以在一个类的设计时如果有构造方法,最好提供一个无参构造方法.因此,系统类库中的类大多提供了无参构造方法,用户编程时最好也要养成此习惯.
【注意】使用this查找匹配的方法时首先在本类查找,找不到时再到其父类和祖先类查找;使用 super 查找匹配方法时,首先到直接父类查找,如果不存在,则继续到其祖先类逐级往高层查找。
2. final修饰符的使用
1.final作为类修饰符: 这种类成为最终类,特点是不允许继承.例如Api中的Math,String,Integer类都是final类.
2.final修饰方法: 是功能和内部语句不能被更改的最终方法,在子类中不能再对父类的final方法重定义.所有private修饰的为私有方法和final类中的方法都默认为是final.
3.final定义常量:只能被赋值一次 例如 final double PI=3.14159;
//注意带static的类常量只能在定义或静态代码块中赋值
4.内部类只能访问被final修饰的局部变量。
3. 抽象类和抽象方法
1.抽象类的定义:抽象类代表了一种优化了的概念组织方式,来描述事物的一般状态和行为,然后在子类中去实现这些状态和行为,以适应对象的多样性.
abstract class 类名称{
成员变量;
方法(){……} //一般方法,可存在,可也不存在
abstract 方法(); //抽象方法
}
说明:抽象类中可以包含具体方法和抽象方法,抽象方法的定义与具体方法不同,抽象方法在后直接跟分号,而具体方法都含有方法体.
//普通类加上abstract关键字就变成了抽象类,没有任何条件限制.但是有抽象方法的类必须定义为抽象类,否则会提示"The type XXX must be an abstract class to define abstract methods"
2. 抽象方法表示一个抽象的概念,不能被实例化为对象.
3.抽象类中是有默认的构造函数.我的理解是不过隐藏了不能直接建立对象罢了.当然自己也可以写自己的构造函数. 抽象类中的构造方法供子类实例化调用。
抽象关键字abstract不可以和哪些关键字共存?
private 私有内容子类继承不到,所以,不能重写。
但是,abstract修饰的方法,要求被重写。两者冲突。
final
final修饰的方法不能被重写。
而abstract修饰的方法,要求被重写。两者冲突。
static
假如一个抽象方法能通过static修饰,那么这个方法,就可以直接通过类名调用。
而抽象方法是没有方法体的,这样的调用无意义。所以,不能用static修饰。
牵扯到的模版方法设计模式
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的.就将不确定的部分暴露出去,有该类的子类去完成.
4. 接口
Java中不支持多继承,而是通过接口实现比多重继承更强的功能,java通过接口可以使出于不同层次,甚至不相关的类具有相同的行为.可认为是一种特殊的抽象类.
1.接口的定义:由常量和抽象方法组成
[public] interface 接口名 [extends 父接口名列表 ] {
[public] [static] [final] 域类型 域名 = 常量值 ;
[public] [abstract] 返回值 方法名(参数列表) [throw 异常列表];
}
[1]声明接口可给出访问控制符;
[2]一个接口还可以继承多个父接口,父接口间用逗号分隔。
[3]系统默认接口中所有属性的修饰都是public static final,毕老师说的全局常量.
[4]系统默认接口中所有方法的修饰都是public abstract;即抽象方法.
接口是抽象类的一种,不能用于直接创建对象.接口的作用在于规定一些功能框架,具体功能的实现则通过该接口约束的类完成.
2.接口的实现
接口定义了一套行为规范,一个类实现这个接口就是要遵守接口的定义规范,要实现接口中定义的所有方法.
一个类可以实现多个接口。接口间用逗号分隔;
如果实现某接口的类不是抽象类,则在类的定义部分必须实现指定接口的所有抽象方法;否则编译时会指示该类只能为抽象类是不能创建对象的.
接口的抽象方法的访问限制符默认为 public,在实现时要在方法头中显式地加上public修饰。
5. 多态性(体现在父类或者接口的引用指向或者接收自己的子类对象)
作用:
多态的存在提高了程序的扩展性和后期可维护性.但弊端是父类的引用只能访问父类中的成员.
前提:
• 需要存在继承或者实现关系
• 要有覆盖操作
1.方法的重载
方法调用的匹配处理原则是,首先按“精确匹配”原则去查找匹配方法,如果找不到,则按“自动类型转换匹配”原则去查找能匹配的方法。
所谓“精确匹配”就是实参和形参类型完全一致。
所谓“自动转换匹配”是指虽然实参和形参类型不同,但能将实参的数据按自动转换原则赋值给形参。
2.方法的覆盖
方法名、参数列表、完全相同才会产生方法覆盖;返回类型通常也要一致,只有返回类型为引用类型时,允许子类方法的返回类型是父类方法返回类型的子类型。其他情形导致类型不一致时编译将指示错误。
覆盖不能改变方法的静态与非静态属性。子类中不能将父类非静态方法定义为静态方法,反之也一样。
不允许子类方法的访问修饰符比父类有更多的限制。例如:子类不能将父类的public方法定义为protected方法。但可以将父类的private方法在子类中重新定义为public方法.通常将子类方法访问修饰符与父类保持一致.
final方法不能被覆盖。
[注意] 如果子类中定义了与父类同名的属性,在子类中将隐藏来自父类的同名属性变量. 对象执行方法时由实际对象的类型决定,而不是引用变量类型 ;
访问属性时则由引用类型决定,因为编译程序在分析程序时是基于类型来决定访问哪个属性变量 ;
静态成员的访问是基于引用类型,而不是对象类型.
3.访问继承的成员
得知通过子类对象赋值给父类的引用变量后,通过该引用变量去访问对象的成员时,访问的行为方法是子类对象的,而属性值确是父类的.其实就是编译系统是基于类型来决定的.
是基于引用类型/实际对象?
当子类和父类有相同成员时,通过子类引用访问的成员都是子类定义的,而通过父类引用变量操作子类对象时,只有实例方法存在覆盖关系(编译时看左边:要查看引用变量所属的类中是否有所调用的成员。在运行看右边:要查看对象所属的类中是否有所调用的成员),而对象属性,静态属性,静态方法均是父类定义的.
4.几个特殊类
Object类: 所有Java类的最终祖先,编译系统默认继承Object类,Object类包含了所有Java类的公共属性和方法,下面是四个常用方法.
public boolean equals(Object obj) :该方法本意用于两个对象的“深度”比较,也就是比较两对象封装的数据是否相等;而比较运算符“==”在比较两对象变量时,只有当两个对象引用指向同一对象时才为真值。但在Object类中,equals方法是采用“==”运算进行比较;
public String toString():该方法返回对象的字符串描述,建议所有子类都重写此方法。
public final Class getClass():返回对象的所属类;
protected void finalize(): 该方法Java垃圾回收程序在删除对象前自动执行。
Class类
1.获取Class类型的对象
Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。有以下3种方法可以获取Class的对象。
方法1:调用Object类的getClass()方法。
方法2:使用Class类的forName()方法。
方法3:如果T是一个Java类型,那么T.class就代表了与该类型匹配的Class对象。例如,String.class代表字符串类型,int.class代表整数类型。
2.Class类的常用方法
java运行环境中提供了反射机制,这种机制允许程序中动态获取类的信息,以及动态调用对象的方法.
[1] static Class<?> forName(String className):返回给定串名相应的Class对象。
[2] T newInstance():创建类的一个实例。
[3] String getName():返回Class对象表示的类型(类、接口、数组或基类型)的完整路径名字符串。
[4] Method[] getMethods():返回当前Class对象表示的类或接口的所有公有成员方法对象的数组。
进一步利用Method类提供的invoke方法可实现相应类的成员方法的调用。
Object invoke(Object obj,Object[ ] args)
其中,obj代表调用该方法的类实例对象,args代表存放方法参数的对象数组。
Method getMethods(String name,Class…parameterType):返回指定方法名和参数类型的方法对象。
Field[ ] getFields():返回当前Class对象表示的类或接口的所有可访问的公有域对象的数组。
6. 对象引用转换
对象引用赋值转换: 允许将子类对象赋值给父类引用,父类表示的范围比较广,反之则不行.
对象引用强制转换
将父类引用赋值给子类变量时要进行强制转换,强制转换在编译时总是认可的,但运行时的情况取决于对象的值.如果父类对象引用指向的就是该子类的一个对象,则转换是成功的.否则会抛出异常.
7. 内部类(一个类定义在另一个类里面)
访问特点: 内嵌类经过编译后产生的字节码文件名为:OuterOne$InnerOne.class
1.内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类的成员,是因为内部类中持有了一个外部类的引用,格式: 外部类名.this
2.外部类要访问内部类,必须建立内部类的对象。
内部类可以使用访问控制符public、protected、private修饰
静态inner类(只能访问外部内的静态成员,出现了访问局限)
内部类定义在成员位置上
• 可以被private static成员修饰符修饰。
• 被static修饰的内部类只能访问外部类中的静态成员。
内部类在定义在局部时(方法中的内部类):
内部类可以直接访问外部类中的成员。
内部类在局部位置上只能访问局部中被final修饰的局部变量。
匿名内部类
Java允许创建对象的同时定义类的实现,但是未规定类名,视为匿名内部类.
1.匿名内部类是内部类的简写
2.定义匿名内部类的前提: 必须是继承一个类或实现接口.
7. 访问控制修饰符
1.公共访问控制符public
[1]作为类的修饰符,将类声明为公共类, 表明它可以被所有的其它类所访问和引用
[2]作为类的成员的访问修饰符,表明在其他类中可以无限制地访问该成员。
要真正做到类成员可以在任何地方访问,在进行类设计时必须同时满足两点:首先类被定义为public,其次,类的成员被定义为public。
2.默认访问控制符
没有给出访问控制符情形,该类只能被同一个包中的类访问和引用,不能被其他包中的类使用.
3.私有访问控制符private
用来声明类的私有成员,它提供了最高级的保护.用private修饰的域和方法只能被该类自身访问和修改,不能被任何其他类(包括该类的子类)来获取和引用.
通常,出于系统设计的安全考虑,将类的成员属性定义为private保护起来,而类的成员方法public对外公开,这是类封装特性的一个体现.
4.保护访问控制符protected
用protected修饰的成员可以在三种类中所引用:
该类本身;与它在同一个包中的其它类;在其它包中的该类的子类.
图7.1
04_Java面向对象特征之继承与多态的更多相关文章
- C#基础总结之八面向对象知识点总结-继承与多态-接口
.方法深入讲解(返回值,形参与实参) 方法 public int getName(int i,int j) { int sum = i + j; return sum; } .利用泛型存储对象数据 . ...
- Python3 与 C# 面向对象之~继承与多态 Python3 与 C# 面向对象之~封装 Python3 与 NetCore 基础语法对比(Function专栏) [C#]C#时间日期操作 [C#]C#中字符串的操作 [ASP.NET]NTKO插件使用常见问题 我对C#的认知。
Python3 与 C# 面向对象之-继承与多态 文章汇总:https://www.cnblogs.com/dotnetcrazy/p/9160514.html 目录: 2.继承 ¶ 2.1.单继 ...
- Python面向对象中的继承、多态和封装
Python面向对象中的继承.多态和封装 一.面向对象的三大特性 封装:把很多数据封装到⼀个对象中,把固定功能的代码封装到⼀个代码块, 函数,对象, 打包成模块. 这都属于封装思想. 继承:⼦类可以⾃ ...
- C实现面向对象封装、继承、多态
参考资料: http://blog.chinaunix.net/uid-26750235-id-3102371.html http://www.eventhelix.com/rea ...
- PHP的面向对象 — 封装、继承、多态
K在上一次的基础篇中给大家介绍了一下关于PHP中数组和字符串的使用方法等,这一次,K决定一次性大放送,给大家分享一下PHP中面向对象的三大特性:封装.继承.多态三个方面的知识. 一.封装 在PHP中, ...
- Python3 与 C# 面向对象之~继承与多态
2.继承¶ 代码裤子:https://github.com/lotapp/BaseCode 在线编程:https://mybinder.org/v2/gh/lotapp/BaseCode/mast ...
- 九、Java基础---------面向对象封装、继承、多态
封装 1.1 基本概念 封装(encapsulation)是面向对象三大特征之一,它是指将对象的状态信心隐藏在对象的内部,不允许外部直接进行访问,而是通过该类提供的方法来实现对内部信息的操作和访问. ...
- python 面向对象及封装继承和多态
######装饰器######装饰器的概念 - 装饰器的实现是函数里面嵌套函数;- 装饰器的本质是一个函数, 它可以让其他函数在不需要做任何代码改动的前提下增加额外的功能;- 装饰器需要传递一个函数, ...
- objective-c自学总结(三)---面向对象的封装,继承与多态
面向对象的三大特性 封装 继承 多态 1.封装: 隐藏属性,方法或实现细节的过程称为封装 信息隐藏,隐藏对象的实现细节,不允许用户看到 将东西包装在一 然后以新的完整形式呈现出来 例如,两种或多种化学 ...
随机推荐
- MVP设计模式的实现
MVP:界面与业务逻辑分离在Winform中的应用 MVP,Model-View-Presenter的缩写. 在MSDN上,下载了一个示例,http://www.microsoft.com/china ...
- IOS- 快速排序,冒泡排序,直接插入排序和折半插入排序,希尔排序,堆排序,直接选择排序
/*******************************快速排序 start**********************************///随即取 当前取第一个,首先找到第一个的位置 ...
- 构建新版本APP上传流程
//既然是构建新版本的 APP,那么所有的证书都是已经存在了的,因此以下不再重复描述证书申请过程,如有需要请自行 Google 相关流程. 1)更改版本号: 2)去掉工程内的全局断点,同时关闭僵尸调试 ...
- FILE文件操作
http://www.jb51.net/article/37688.htm fopen(打开文件)相关函数 open,fclose表头文件 #include<stdio.h>定义函数 FI ...
- "稀奇古怪的"delete this
myClass::foo(){ delete this; } .. void func(){ myClass *a = new myClass(); a->foo(); ...
- Intel Code Challenge Elimination Round (Div.1 + Div.2, combined)(set容器里count函数以及加强for循环)
题目链接:http://codeforces.com/contest/722/problem/D 1 #include <bits/stdc++.h> #include <iostr ...
- linux文件描述符open file descriptors与open files的区别
一个文件被打开,也可能没有文件描述符,比如current working diretories,memory mapped files and executable text files ;losf可 ...
- jQuery - 5.样式操作
样式操作 1.获取样式 attr("class"), 2.设置样式attr("class","myclass"), 3.追加样式addCla ...
- Integer Inquiry【大数的加法举例】
Integer Inquiry Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 27730 Accepted: 10764 ...
- makefile示例
1. 生成.so动态库 示例一: SoVer = 10010110CfgVer = 10010110 BinName = fnights.soGameName = "\"fnigh ...