首页 > 代码库 > java随笔:三大特性之继承

java随笔:三大特性之继承

Java三大特性之继承

一、介绍

  笔记重点:构造器、protected关键字(这个自行查阅)、向上转型、private关键字(继承非常重要的要点)

   复用代码是Java众多引人注目的功能之一。但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情。在这句话中最引人注目的是“复用代码”,尽可能的复用代码使我们程序员一直在追求的。

  继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码,能够大大的提高开发的效率。

  为什么要继承?

  答:通过继承可以使对对象的描述更加清晰,可以实现代码的复用,可以实现重写类中的变量或方法。

二、深入理解继承

  1.Java的继承具有单继承的特点,即只能继承一个父类,每个子类只有一个直接父类,但是其父类又可以继承于另一个类,从而实现了子类可以间接继承多个父类,但其本质上划分仍然是一个父类和子类的关系。

  2.Java的继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类称为父类(有的也称其为基类、超类)

  3.子类拥有父类非private的属性和方法。(便于理解是这么和你们说的,这种说法其实是错的 =.=!暂且这么理解好了。)

  4.子类可以拥有自己属性和方法,即子类可以对父类进行扩展。

  5.子类可以用自己的方式实现父类的方法。

  6.为什么国内把extends翻译成继承呢?除了与历史原因有关外,把extends翻译成为继承也是有其道理的:子类扩展父类,将可以获得父类的全部属性和方法,这与汉语中得继承(子辈从父辈那里获得一笔财富成为继承)具有很好的类似性。

三、什么样的类不能被继承呢?

  1.final(终态)修饰的类是无法被继承的,但是也不要误解有final的类都不能被继承。

  Example 1:

        技术分享

    Example 2:

      技术分享

  2.构造器(注意下面有构造器的相关介绍)被private关键字修饰的类无法被继承。必须定义显式构造函数才能被继承(例如被protected与private关键字修饰)。

  Example 1:

        技术分享

 

四、构造器(简单介绍上边有个例子)

  什么是构造器?

  答:简单来说构造器即是与类名相同的特殊方法,但它没有返回值。深入来说Java中引入构造器,确保每一个对象都得到初始化,Java在有能力操作对象之前,系统会自动调用相应的构造器,保证初始化的进行。构造器最大的用处就是在创建对象时执行初始化,当创建一个对象时,系统会为这个对象的实例进行默认的初始化。如果想改变这种默认的初始化,就可以通过自定义构造器来实现。在java中,使用new关键是调用构造器,从而返回该类的实例。也就是说:构造方法是定义在Java类中的一个用来初始化对象的方法,是创建对象的根本途径 。

    使用构造器要注意一下几点:1.如果我们没有自己定义构造方法,系统就会默认为该类提供一个无参的构造器。一旦我们为一个类提供了构造器,系统将不会该类提                     默认无参的构造器。(下面提供例子 Example 1、2 供理解)

                    2.有参的构造方法和无参构造方法是可以同时存在的(方法重载)//不提供例子,自己敲。

                3.构造方法不但可以给属性赋值,还可以保证给对象的属性赋一个合理的值

  Example 1:       

 1 public class test1 {
 2     public static void main(String[] args) {
 3         // TODO 自动生成的方法存根
 4         test2 p=new test2();
 5         System.out.println("Hello");
 6     }
 7 }
 8 class test2{
 9     private String b;
10     //public test2(){}---系统已经默认为该类提供无参的构造方法
11 }

 

  Example 2:

 1 public class test1 {
 2     public static void main(String[] args) {
 3         // TODO 自动生成的方法存根
 4         //new关键是调用构造器,返回该类实例
 5         test2 p=new test2();//报错
 6         System.out.println("Hello");
 7     }
 8 }
 9 class test2{
10     private String b;
11     //因为我们已经定义了有参构造方法,所以系统将不再提供默认的无参构造方法
12     public test2(String b){
13         this.b=b;
14     }
15 }         

  补个重点:在构造器中调用父类构造器来完成初始化,而父类构造器具有执行父类初始化所需要的所有知识和能力。

 1 public class test1 {
 2     public static void main(String[] args) {
 3         // TODO 自动生成的方法存根
 4         //new关键是调用构造器,返回该类实例
 5         test3 p=new test3();//报错
 6         System.out.println("Hello");
 7     }
 8 }
 9 class test2{
10     public test2(){
11         System.out.println("test2");
12     }
13 }
14 class test3 extends test2{
15     public test3(){
16         //super();---已经默认调用父类构造器
17         System.out.println("test3");
18     }
19 }
  输出:
  test2   test3   Hello

 

  解析:子类继承父类是从父类向外扩展的,从父类向子类一层层扩展。子类会默认调用父类的构造器,这个调用是有前提的父类必须要有默认的构造器,如果没有就会报错,编译器会报错:无法找到符合父类形式的构造器

 

 1 public class test1 {
 2     public static void main(String[] args) {
 3         // TODO 自动生成的方法存根
 4         //new关键是调用构造器,返回该类实例
 5         test3 p=new test3();//报错
 6         System.out.println("Hello");
 7     }
 8 }
 9 class test2{
10     public test2(String name){
11         System.out.println("test2------"+name);
12     }
13 }
14 class test3 extends test2{
15     public test3(){
16         super("zs");//---必须调用父类有参构造器
17         System.out.println("test3");
18     }
19 }
  输出:
  test2------zs   test3   Hello

 

  总结:继承时子类会默认调用父类的构造器,但是如果没有默认的父类构造器,子类必须要显示的指定父类的构造器,而且必须是在子类构造器中做的第一件事(第一行代码)。

五、向上转型

  继承中父类与子类是“is a”的关系,比如“学生”类继承了“人”这个类,那么可以说学生是一个人(这就是向上转型)。向上转型是安全的,但是可能会丢失一部分属性和方法(转型过程中,子类的新有的方法都会遗失掉,在编译时,系统会提供找不到方法的错误)。

 

 1 public class test1 {
 2     public static void main(String[] args) {
 3         // TODO 自动生成的方法存根
 4         //new关键是调用构造器,返回该类实例
 5         test3 p=new test3();//报错
 6         test2 p1=new test2("351");
 7         p1.p(p);//-----转型并且是安全的
 8     }
 9 }
10 class test2{
11     public test2(String name){
12         System.out.println("test2------"+name);
13     }
14     public void p(test2 p1){
15         System.out.println("+++++");
16     }
17 }
18 class test3 extends test2{
19     public test3(){
20         super("zs");
21         System.out.println("test3");
22     }
23 }

 

扩展:

         1、父类变,子类就必须变。

 

         2、继承破坏了封装,对于父类而言,它的实现细节对与子类来说都是透明的。

     3、其实子类不仅拥有父类的非private的属性和方法,也拥有父类的private的属性和方法。首先需要明确:private、public和protected这几个关键字,和继承没有关系,有关系的应该叫做“可见性”。父类不能控制自己的成员被子类继承走,但是可以约束某些被继承的成员变量,对于子类来说是不可见的。

    (个人理解为子类拥有父类的所有属性和方法只是无法使用,这个不是瞎扯是可以查出来的)。

 

java随笔:三大特性之继承