Java学习——继承

来源:互联网 发布:get it 和 Got it 编辑:程序博客网 时间:2024/05/21 03:25

1.继承是一种由已有的类创建新类的机制。利用继承,可以先定义一个共有属性(在设计模式中,也就是把不变的、固定的那部分属性、方法抽取出来作为子类的共有属性)的一般类(父类、超类或基类),根据该一般类再定义具有特殊属性的子类,子类继承一般类的属性和行为(注意private和protected修饰),并可以根据需要增加子类自己新的属性和行为。

继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。

2.在类的声明中,通过使用关键字extends(延伸、延续)来定义一个类的子类。如果一个类的声明中没有extends关键字,这个类被系统默认为是Object的子类,即类声明 “class A” 和 “class A extends Object”是等同的。

Java中所有的类都继承自Object,任何类都是Object的子孙类,每个类(除了Object类)有且仅有一个父类,一个类可以有多个或零个子类。

3.java虚拟机的运行机制要求一个java文件里只能有一个class前边有public的修饰符,而且这个class必须和java文件同名。如果你想在一个java文件里放置多个class文件,只需要把他们前面的public修饰符去掉,留下和java文件同名的那个即可。否则的话你就要把每个class都放到一个单独的java文件里才行。

OJ判题时只能用第一种方法,可是在做项目时应当用后一种,这样更清晰,当修改时更容易定位。

4.子类的继承性:

  • 如果子类和父类在同一个package中,子类自然的继承了父类中不是private的成员变量和成员方法作为自己的成员变量、方法,继承的成员变量或方法的访问权限保持不变。
  • 当子类和父类不在同一个包中时(注意此时要给每个文件类前加public,否则子类无法继承),父类中的private和友好访问权限的成员变量不会被子类继承,也就是说,此时,子类只继承父类中的protected和public访问权限的成员变量、方法作为子类的成员变量、方法

如果一个类中想要使用的类和它不在一个包中,这时可以通过import语句来引入包中的类。在一个Java源程序中可以有多个import语句,但它们必须写在package语句(如果有package的话)和源文件中的类定义之间。比如,常用的scanner类(用户编写的类肯定和类库中的类不在同一个包中)的import引入:import java.util.Scanner; 如果要引入一个包中的全部类,可以通过使用通配符星号” * “来代替。 注意:java.lang包是Java语言的核心类库(包含所有的基本语言类),它包含了运行Java程序必不可少的系统类,系统会自动为程序引入java.lang包中的类,因此不需要再使用import语句引入该包中的类。

5.注意:子类在创建对象时,其父类的成员变量也全都分配了内存空间,但只有子类继承的那部分成员变量,作为分配给子类对象的变量。尽管看起来好像是子类在创建对象时创建了一些垃圾变量(无法直接访问),但是子类中还有一部分变量是从父类继承来的,而这部分方法有的是可以操作这部分未继承的变量的。

6.Java不像C++一样支持多重继承,即其子类只能有一个父类,但这可以通过实现”接口“来完成。子类与父类的关系是“is a”关系,example:“学生”是“人”。

在java中不容许继承两个或两个以上的类。像这样class C extends A,B(多重继承);是不允许的;而class B extends A; class C extends B 是可以的。

6.成员变量的隐藏和方法重写:

  • 如果创建的子类的成员变量的名字和父类的成员变量名字相同(类型可以不同),在这种情况下,子类就会隐藏所继承的成员变量。但是子类对象仍然可以调用从父类继承的方法操作被子类隐藏的成员变量(毕竟只是名字相同),也就是说子类继承的方法所操作的成员变量一定是(只能是)被子类继承或隐藏的成员变量。子类新定义的方法可以操作子类继承和子类新声明的成员变量,但无法操作子类隐藏的成员变量(需使用super关键字操作子类隐藏的成员变量)。
  • 子类通过重写可以隐藏已继承的方法。方法重写是指子类中定义的方法的类型和父类的方法的类型一致或者是父类的方法的子类型(子类型是指如果父类的方法的类型是“类”,那么允许子类的重写方法是“子类”),并且这个方法的名字、参数个数、参数类型和父类的方法完全相同。注意:重写父类方法时,不允许降低方法的访问权限,但可以提高权限,访问限制修饰符按访问权限从高到低的排列顺序是“public、protected、友好的、private”。

7.如果想在子类中使用被子类隐藏的成员变量或方法就需要使用关键字super,如super.x,super.play()。当用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法,但由于子类不继承父类的构造方法,所以子类在其构造方法中需使用super关键字来调用父类的构造方法。而且,注意如果子类中有新的自定义的成员,也需要对其在构造函数中初始时,super必须是子类构造方法中的头一条语句,即如果在子类的构造方法中,没有明显地写出super关键字来调用父类的某个构造方法,哪么默认的会有:super();

public class Student extends People{    public int grade = 0;    public double test=-0.99;    public Student(String name, int age,int grade) {        super(name, age);//使用super调用父类的构造方法,如果将这条语句注释了,父类中就必须要有默认的构造方法。        // TODO Auto-generated constructor stub        this.grade = grade;    }    public void out(){        System.out.println("father:"+super.test+",son:"+this.test);    }    public void show(){        System.out.println("son:!");        super.show();    }}

使用super调用父类的构造方法,但如果子类的构造方法没有明显地指明使用父类的那个构造方法,子类就调用父类的不带参数的构造方法(即默认的构造方法),但如果类里定义了一个或多个构造方法,哪么Java就不提供默认的构造方法,所以在父类中定义多个构造方法时,应当包含一个不带参数的构造方法,以防子类省略super时出现错误。

8.final关键字修饰类、成员变量和方法中的局部变量。

  • final类不能被继承,即不能有子类。例如出于安全性的考虑,String类就是一个final类,不允许用户程序扩展String类。
  • 如果final方法修饰父类的一个方法,那么这个方法不允许子类重写,即子类必须老老实实的继承,不允许做任何改动。
  • final如果修饰的是变量,那代表着这是常量(常量命名所有单词都是大写)。注意,在声明常量时,程序必须指定该常量的值(因为常量在声明时没有默认值,如果没有初始化,其实在Eclipse中在使用该常量时会报错!)。

9.多态性是指父类的某个方法被其子类重写时,可以各自产生自己的功能行为。
用关键字abstract修饰的类称为抽象类,用abstract修饰的方法称为抽象方法。
注意对于abstract方法,只允许声明,不允许实现(没有方法体),而且不允许使用final和abstract同时修饰一个方法或类,也不能用static修饰abstract类。
abstract类即可以有abstract方法,也可以有非abstract方法。
abstract类不能用new运算符创建对象。如果一个非抽象类是某个abstract类的子类,那么它必须重写父类的抽象方法,给出方法体,这就解释了不允许使用final和abstract同时修饰一个方法或类的原因(因为有着本质上的矛盾)。
所以abstract类想要使用就必须要继承。抽象类可能仅仅代表一个分类或抽象概念,它的实例没有任何意义,因此不希望它能被实例化。但从继承的角度看还是很有可取之处的,因为毕竟有些子类是具有共性的!

面向抽象编程的核心是让类中每种可能的变化对应地交给抽象类的一个子类去负责,从而让该类的设计者不去关心具体实现,避免所设计的类依赖于具体的实现。面向抽象编程设计的类使得开发人员可以更容易面对用户需求的变化。

1 0