继承
概念
继承是面向对象编程的三大特征之一,也是实现代码复用的重要手段。java中继承具有单继承的特点,每一个类只可以直接继承一个父类,即直接父类,不可以同时继承多个类。但是继承是可以多层继承的,即:父类还有父类,顶级的父类为Object类。也就是说,任何类都是Object的子类,Object是任何类的父类。
如果编写的类没有直接继承其他类,默认继承的是Object类
子类 了父类的一些特征。子辈从父辈那里可以继承一笔财富称为继承,子类从父类那里可以继承一些代码称为继承。
继承是如何实现代码的复用?
以已有的类作为父类(基类),从这个父类已有的功能和属性上,在新的类(子类)中,添加其他方法和属性,达到复用代码的目的,而不用再编写父类已存在的代码,这样就达到了代码的复用!
提示:
当我们描述一类事物时候,发现这些事物具备相同的属性,我们将这些共性属性进行抽取,用单独的类来描述共同的属性,让这类事物继承抽取出来的类描述的对象,实现的代码的复用。但是请注意,继承是一类事物共性的向上抽取,所以不能单纯的为了简写代码而使用继承。
JavaJDK中提供了大量的类,这些类通过一层一层的继承,形成一个庞大的继承树,最顶级为Object类,一定要注意,这个继承树的形成是N多个类的共性的抽取,一层一层抽取共性,直至抽取到Object类,而不是说:所有功能的类都是通过Object派生出去的!
//描述猫的时候,继承狗,虽然也具备了name属性,但是意义完全错误。
class Cat extends Dog
{
String id;
}
如果在描述对象时,只是为了简写代码,不可以使用继承的特性定义了一些和描述对象完全不相关的成员。
如果只是为了简写代码的编写,完全可以将这些不相关的代码编写一个单独的工具类来实现。
class Dog {
Stringname;
Stringage;
voidmethod1(){
System.out.println("今天星期一");
}
voidmethod2(){
System.out.println("天气晴");
}
voidmethod3(){
System.out.println("今天没雾霾");
}
}
class DaoMang extends Dog
{
/*在这里编写代码时候,需要用到父类的方法,可以
直接调用,编写代码确实很爽,但是这和继承思想
完全没有任何关系!因为执行父类的那些方法和描述
对象没有任何关系!!*/
voidmethod(){
method1();
}
}
编写dog继承类代码。
class Dog {
Stringname;
Stringage;
voidworking(){
System.out.println("看家!");
}
}
class DaoMang extends Dog
{
String id;
}
特点:
java继承通过使用extends关键字来实现,实现继承的类被称为子类,被继承类称为父类。例如:动物是狗的父类,狗是哈士奇的父类。
定义格式:
修饰符 class 子类 extends 父类{
}
重写:Override:
子类继承父类后,在原有的基础上可以进行扩展,如新增属性、方法,但是有一种情况,例如:狗类具有工作方法搜救犬的工作是搜救,导盲犬的功能是导盲,那这个时候他们的工作方法内容就不一样了,我们需要将他们的工作方法进行单独的修改,那么这个修改的动作就是重写。
定义:子类继承父类后,如果子类的方法与父类的方法名称、参数个数及返回值类型完全一致时,就称为子类中的这个方法重写了父类中的方法。同理,如果子类中重复定义了父类中的已有的属性,则称此子类中的属性重写了父类中的属性。
子类重写了父类的方法或属性,那么该方法或属性便属于子类,而不属于父类,如果还想调用父类中的被重写的方法或属性,使用super.方法名/参数名的方式调用即可。
class Test
{
publicstatic void main(String[] args){
DaoMangdm = new DaoMang();
dm.working();
Soujiusj = new Soujiu();
sj.working();
}
}
class Dog {
Stringname;
Stringage;
void working(){
System.out.println("看家!");
}
}
class DaoMang extends Dog
{
String id;
voidqita(){
}
voidworking(){
System.out.println("引路!");
}
}
class Soujiu extends Dog
{
String id;
voidworking(){
System.out.println("搜救!");
}
}
spuer关键字
定义: super代表当前对象的父类对象。
当创建子类对象,最先拥有的应该是它的父类对象,那么可以使用super关键字代表父类对象,达到访问父类成员的目的!
父类对象都没有怎么可能创建子类对象?
子类覆盖了父类的方法后,子类对象无法直接调用被覆盖的父类中的方法,那么可以使用super关键字来实现调用父类的方法,或者也可以使用类名.方法名调用,但前提这个方法是静态方法(类方法)。
通过super找到该对象的父类对象:
voidworking(){
super.working();
System.out.println("引路!");
}
通过Dao.静态方法执行代码:
static void working(){
Dog.working();
System.out.println("引路!");
}
之前的this关键字是代表当前对象本身。这个时候super代表的是父类对象本身。
同样,super和this不能出现在static关键字修饰的方法中。
因为:static修饰的是静态的,super、this关键字描述的是对象,静态成员是优先于对象存在的。用存在的东西访问不存在的东西是错误的。
验证:子类调用到父类的属性,该属性属于父类而不属于子类。
1、 在父类中定义name属性,子类没有定义name属性。
2、 在测试时候,调用子类的name属性。
3确定这个子类修改了的name属性其实是属于父类的!
证明:
1、 父类对象被子类引用。
2、 子类继承父类的属性,只是引用指向了父类,并没有将父类的属性进行单独的复制一份作为子类对象本身的属性。
导盲犬与搜救犬的父类对象是同一个吗?
每次创建子类对象,都会单独创建一个该子类的父类对象!他们的父类对象不是同一个,但是他们的父类是同一个!
调用父类构造器:
class Dog {
publicDog(String message){
System.out.println(message);
}
Stringname;
}
class DaoMang extends Dog
{
publicDaoMang(){
super("abc");
}
String id;
static void working(){
System.out.println("引路!");
}
}
创建一个子类对象,发生了什么未知的事情?
class Test
{
publicstatic void main(String[] args){
/*
创建子类对象发生了:
1、先执行父类静态代码块
2、执行子类静态代码块
3、执行父类的构造代码块
4、执行父类的构造方法
5、执行子类的构造代码块
6、执行子类的构造方法
*/
DaoMangdm = new DaoMang();
}
}
class Dog {
static{
System.out.println("Dog类的静态代码块执行了!");
}
{
System.out.println("创建Dog对象时构造代码块");
}
publicDog(){
System.out.println("Dog的构造器执行了!");
}
}
class DaoMang extends Dog
{
static{
System.out.println("DaoMang类的静态代码块执行了!");
}
{
System.out.println("创建DaoMang对象时构造代码块");
}
publicDaoMang(){
System.out.println(id + "DaoMang的构造器执行了!");
}
}
设置父类与子类同名的成员属性
class Test
{
publicstatic void main(String[] args){
DaoMangdm = new DaoMang();
dm.setName("金毛");
dm.setSuperName("SuperName");
Stringname = dm.getName();
StringsuperName = dm.getSuperName();
System.out.println("子类对象的name:" + name +"\n 父类对象的name是:" + superName);
}
}
class Dog {
Stringname;
}
class DaoMang extends Dog
{
Stringname;
publicvoid setName(String name){
this.name= name;
}
publicvoid setSuperName(String name){
super.name= name;
}
publicString getName(){
returnname;
}
publicString getSuperName(){
returnsuper.name;
}
}