JAVA_Lesson9(传智播客笔记之继承、抽象、接口)

子父类中构造函数的特点:

Class Fu
{
  Fu()
  {
     Sop(“Fu run”);
  }
  Fu(int x)
  {
     Sop(“fu run...”+x);
  }
}
Class Zi extends Fu
{
   Zi()
   {    //super();其实这里省略了这条语句,调用的就是父类中的空参数的构造函数。而this()则代表本类中的构造函数(这句是隐式的)访问的是空参的父类中的构造函数,如果父类中的构造函数不是空参的,那么super()里面也需要传参数,不然会出问题。
     Sop(“Zi run”);
     }
}
Class ExtendsDemo4
{
   Public static void main(String[]args)
   {
      New Zi();
   }
}

运行结果为:fu run

                   Zi run

    构造函数没有覆盖之说,也没有继承之说。

  子类的实例化(对象)过程:子类中所有的构造函数默认都会访问父类中的空参数的构造函数。

Class Fu
{
    Fu()
   {
      Sop(“A Fu run”);
    }
    Fu(int x)
   {
      Sop(“B fu run...”+x);
   }
}
Class Zi extends Fu
{
   Zi()
   {    //super();其实这里省略了这条语句,调用的就是父类中的空参数的构造函数。而this()则代表本类中的构造函数(这句是隐式的)访问的是空参的父类中的构造函数,如果父类中的构造函数不是空参的,那么super()里面也需要传参数,不然会出问题。
   Sop(“ C Zi run”);
   }
   Zi(int x)
   {
      Sop(“D zi run”);
   }
}
Class ExtendsDemo4
{
   Public static void main(String[]args)
  {
    New Zi(6);
  }
}

打印结果为:AD(这个我自己做对了,稍微看看就行)

为什么子类实例化的时候要访问父类中的构造函数呢?

    那是因为子类继承了父类,获取了父类中内容(属性),所以在使用父类内容之前,要先看父类是如何对自己的内容进行初始化的。所以子类在构造对象时,必须访问父类中的构造函数。为了完成这个必须的动作,就在子类的构造函数中加入了super()语句。如果父类中没有定义空参数构造函数,那么子类的构造函数就必须要用super明确要调用父类哪个构造函数。(总之就是要匹配了

注意:super语句必须要定义在子类函数的第一行,因为父类的初始化函数必须要先完成。

This()是调用本类中的构造函数。子类构造函数中如果使用this调用本类构造函数时,super就没有了,因为superthis都只能定义第一行。但是可以保证的是,子类中最少有一个构造函数访问父类的构造函数。

    权限:类名若有public的话,那么里面的构造函数就默认也是public。父类其实也有爹,就是ObjectObject类是java中最顶层的类,是java的上帝。

      子类的实例化过程(图解)

    注:对代码进行修改后,只需ctrl+S保存后,不需要关闭文件,文件打开状态,即可对文件进行编译操作。

    下面这个例子跟自己想象中的运行结果有点反差(务必要弄懂这个示例):

    关键就是子父类显式、隐式初始化问题:

为什么子类实例化的时候要访问父类中的构造函数呢?

那是因为子类继承了父类,获取了父类中内容(属性),所以在使用父类内容之前,要先看父类是如何对自己的内容进行初始化的。所以子类在构造对象时,必须访问父类中的构造函数。为了完成这个必须的动作,就在子类的构造函数中加入了super()语句。如果父类中没有定义空参数构造函数,那么子类的构造函数就必须要用super明确要调用父类哪个构造函数。(总之就是要匹配了

注意:super语句必须要定义在子类函数的第一行,因为父类的初始化函数必须要先完成。

This()是调用本类中的构造函数。子类构造函数中如果使用this调用本类构造函数时,super就没有了,因为superthis都只能定义第一行。但是可以保证的是,子类中最少有一个构造函数访问父类的构造函数。

权限:类名若有public的话,那么里面的构造函数就默认也是public。父类其实也有爹,就是ObjectObject类是java中最顶层的类,是java的上帝。

子类的实例化过程(图解)

注:对代码进行修改后,只需ctrl+S保存后,不需要关闭文件,文件打开状态,即可对文件进行编译操作。

下面这个例子跟自己想象中的运行结果有点反差(务必要弄懂这个示例):

关键就是子父类显式、隐式初始化问题:





一个对象的实例化过程(就是刚刚分析内存图解的过程):

1. JVM会读取指定路径下的Person.class文件,并加载进内存,并会先加载Person的父类。(如果有直接父类的的情况下)

2. 在堆内存中开辟空间,分配地址。

3. 并在对象空间中,对对象中的属性进行默认初始化。

4. 调用对应的构造函数进行初始化。

5. 在构造函数中,第一行会先到调用父类中的构造函数进行初始化。

6. 父类初始化完毕后,再对子类的属性进行显示初始化。

7. 再进行子类构造函数的特定初始化。

8. 初始化完毕后,将地址值赋值给引用变量。

Class Zi extends fu
{
   Int num=8;
   Zi()
  {
     Super(); //这一步的时候num=0;
//到这里的时候,num就已经为8了。
     num=10;//然后到这里的时候,num就为10了。(初始化的顺序)

   }	

}

Final关键字

用个示例来感受下:

class Fu
{
   Void method()
  {
     //调用底层系统的资源
  }
}
Class Zi extends Fu
{
   Void method()
   {
      Sop(“haha”); //继承的弊端可以打破父类的封装性,一继承一覆盖。
   }

}
Class FinalDemo
{
   Public static void main()
  {
     Sop(“hello world”);
   }

}

Final关键字就是用于解决这个问题的。不让你继承。只需要final class fu

1. final是一个修饰符,可以修饰类、方法、变量

2. Final修饰的类不可以被继承(编译会出错)

3. 但是如果类中有部分想被继承,该怎么办呢? 此时只需将final加在方法上,也即是final修饰的方法不可被覆盖

4. 开发常用:修饰变量时:

Final修饰的变量是一个常量,只能赋值一次。

Final double PI=3.14;(不能直接用3.14,阅读性,必须要取名字)

Final默认显示初始化值,没有默认初始化值。一般成员被final了,一般都会加static,其他看自己的需求。

为什么要用final修饰变量?

其实在程序中如果一个数据是固定的,那么直接使用即可。但是阅读性差,所以该数据起个名称而已。而且这个变量名称不能变化,所以加上final固定。

写法规范:

  常量所有字母都大写,多个单词,中间用下划线连接

抽象类

抽象函数所在的类也必须标志为抽象的。这也就是抽象类的由来。当一个类没有足够的信息来描述该事物,该事物就可抽象。

抽象类的特点:

1. 方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰。抽象方法必须定义在抽象类中。该类必须也被abstract修饰。

2. 抽象类不可以实例化。(因为里面根本没有运行体,调用抽象方法没有意义)

抽象类必须有其子类覆盖了所有的抽象方法后,该子类才可以实例化

3. 抽象类必须有其子类覆盖了所有的抽象方法后,该子类才可以实例化。

五个问题

1.抽象类中有构造函数吗?

我猜对了,嘿嘿。有,抽象类中也是可以有构造函数的。虽然抽象类不能实例化,但是抽象类被继承之后,它的派生类(子类)可以实例化

2. 抽象类可以不定义抽象方法呢?

可以,但是很少见。目的是不让该类创建对象。AWT的适配器就是这种类,通常这个类中的方法有方法体,但是没有内容。

3. 抽象关键字不能和哪些关键字共存?(非法修饰符组合)

  Final我答对了(水火不容的),因为final不让覆盖,而abstract可以覆盖,所以矛盾。

   Private不行,抽象方法需要覆盖,但是若私有后,人家都不知道你有没有方法,还谈什么覆盖操作。

  Static也不行,成员若是静态,对象都不需要创建了,类名就可以直接调用。

4. 一般类中不可定义抽象方法,只能定义非抽象方法。

抽象类中可定义抽象方法,同时也可以定义非抽象方法。一般类可以被实例化,而抽象类不可以被实例化。

5. 抽象类一定是父类吗?

这个好理解。因为需要子类覆盖其方法后才能对子类实例化。

接口定义  

当一种抽象类中的方法都是抽象的时候,这时可以将该抽象类用一种形式定义和表示,就是interface定义接口使用的关键字不是class,是interface但是编译完后还是.class文件。Interface仅仅换了一种表现方式。

对于接口中参加的成员:而且这些成员都有固定的修饰符

1. 全局常量:public static final

2. 抽象方法:public abstract

由此可见,接口中的成员都是公共的权限。即使漏写了修饰符,编译器会给你补齐。但是最好不要这样做,阅读性较差。

接口实现

之前抽象类,后面的类可以继承。而现在接口里面全是抽象的,全部都得重写。所以叫做实现。(类与类之间继承关系,类与接口之间是实现关系)

接口不可以实例化,只能实现了接口的子类并覆盖了接口中所有的抽象方法,该子类才可以实例化(也就是创建对象)。

 接口的多实现

java中不直接支持多继承,因为会出现调用的不确定性。所以java将多继承机制进行改良,在java中变成了多实现。一个类可以实现多个接口。

Interface A
{
   Public static void show();
  {
   }
}
Interface Z
{
   Public static void showZ()
   {
   }
}
Class Test implements A,Z
{
}  

若接口AB中的均是一样的方法show(),可以在Test中同时覆盖。多继承就是因为有方法体,会导致运行结果不一样。而现在接口里面都没有方法体了,故而可行。(Java的改良),因为现在没有不确定性了。

Interface A
{
   Public void show();
}
Interface Z
{
    Public void show(); //若改为int的话,则会编译失败,下面根本都没有对应的覆盖。可能不服气,在下面Test类中加上public int show() {} ,还是会编译失败,因为Test里实现的时候返回都不知道返回什么类型的值,2个返回值类型不同的show方法。人家都不知道该返回哪一个。
}
Class Test implements A,Z
{
   Public void show()
  {
  }
}

接口的细节

 Class Test2 extends Q implements A,Z 这样功能就丰富多了。

接口的出现避免了但继承的局限性。接口与接口之间是什么关系呢?(两个都是抽象的)

Interface CC
{
  Void show();
}
Interface MM
{
   Void method();
}
Interface QQ extends CC,MM
{
   Void function();
}//接口与接口之间是继承关系,而且接口可以多继承。接口可以被类多实现,接口之间可以多继承。
Class WW implements QQ
{
   //这就需要覆盖3个方法
  Public void show()
  {}
  Public void method()
  {}
  Public void function()
  {}
}

接口的特点

Ps2(早期鼠标的接口那种圆形的)----现在的USB接口,其实说白了,接口就是对我暴露的规则,是程序的功能拓展,接口的出现降低了耦合性,接口可以用来多实现。

接口和抽象类的区别

相同点:都是向上抽取而来的。

不同点:1.抽象类需要被继承,而且只能是单继承。接口需要被实现,而且可以多实现

            2.抽象类中可以定义抽象方法和非抽象方法,子类继承后可以直接使用非抽象方法。接口中只能定义抽象方法,必须由子类实现。

3.抽象类的继承是is a关系,在定义该体系的共性内容;而接口的实现是like a关系,在定义该体系的额外功能。

举个例子:

犬按功能分:导盲犬、搜爆犬等

Abstract  class犬
{
   Abstract void 吼叫();
}
Class 导盲犬 extends 犬
{
   Public void 吼叫()
   {
   }
   Public void 导盲()
   {
   }
}

还可以如下这样做:

Abstract class 犬
{
   Abstract void 吼叫();
}
Abstract class 导盲
{
    Abstract void 导盲();
}
Class 导盲犬 extends 犬 interface 导盲
//但是不能多继承,现在要想办法,可以让他们2个变成接口,就可以多实现了。直接让他们2个多接口,但是导盲犬本身属于犬的一种还是继承犬比较合适,导盲属于犬的额外功能。可以让其继承一个再实现另外一个。若是直接在下面里面写死了导盲,可是可以,但是不利于程序的拓展性。
{
    Public void 吼叫()
   {
   }
   Public void 导盲()
  {
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值