继承简介
Posted GEORES
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了继承简介相关的知识,希望对你有一定的参考价值。
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承可以理解为一个对象从另一个对象获取属性的过程。
如果类A是类B的父类,而类B是类C的父类,我们也称C是A的子类,类C是从类A继承而来的。在Java中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类
继承中使用的关键字是extends。类的继承决定了一个对象和另一个对象是否是IS-A(是一个)关系。通过继承,我们能实现一个对象获取另一个对象的属性。
一、继承
通过上面的概述,已经知道了继承,下面通过Code来分析继承:
Animal类:(祖父类)
public class Animal {
public String name = "Animal, 多态成员变量测式,父类对象";
public void show() {
System.out.println("动物....(祖父类)");
}
public void eat() {
System.out.println("动物吃东西....(祖父类)");
}
public void sleep() {
System.out.println("动物睡觉....(祖父类)");
}
}
Mammal类:(父类)
public class Mammal extends Animal {
public String name = "Mammal Animal";
public void fight() {
System.out.println("哺乳动物喜欢打架吗?...(添加新的功能)");
}
public void fly(){
System.out.println("哺乳动物会飞吗?...(添加新的功能)");
}
//测试私有是否可以继承
private void test() {
System.out.println("private...");
}
//测试保护是否可以继承
protected void test(int a) {
System.out.println("protected...(被访问了)");
}
//测试保护是否可以继承
void test(char c) {
System.out.println("default...(被访问了)");
}
}
Cat类:(子类)
public class Cat extends Mammal{
public String name = "Cat";
public void show() {
System.out.println("猫...(对父类的重写)");
}
}
Dog类:(子类)
public class Dog extends Mammal{
public String name = "Dog,验证变量的多态";
public void show() {
System.out.println("狗...(子类对父类的重写)");
}
public void sleep(){
System.out.println("狗睡觉...(子类对父类的重写,验证方法的 多态)");
}
}
ExtendsDemo类:(测试类)
public class ExtendsDemo {
public static void main(String[] args) {
// 验证继承性
System.out.println("@@@@@@@@@ 验证继承性: @@@@@@@@@");
Dog dog = new Dog();
dog.eat();
// 测试继承的权限
System.out.println("\\n\\n@@@@@@@@@ 测试继承的权限: @@@@@@@@@");
Cat cat = new Cat();
// 私有的不能访问
// cat.test();
// 保护和默认的都可以
cat.test(\'c\');
cat.test(1);
// 子类添加新的功能
System.out.println("\\n\\n@@@@@@@@@ 子类添加新的功能: @@@@@@@@@");
Mammal mammal = new Mammal();
mammal.fight();
mammal.fly();
// 验证重写
System.out.println("\\n\\n@@@@@@@@@ 验证重写: @@@@@@@@@");
Animal animal = new Animal();
animal.show();
dog.show();
// 验证多态性
System.out.println("\\n\\n@@@@@@@@@ 验证多态性: @@@@@@@@@");
// 成员变量的多态验证
Animal animal2 = new Dog();
System.out.println(animal2.name);
System.out.println("成员变量的多态,编译看左边,运行也看左边, 也就是调用的是父类的成员变量\\n\\n");
// 成员方法的多态验证
animal2.sleep();
System.out.println("成员方法的多态,编译看左边,运行也看右边, 也就是调用的是子类的成员方法");
}
}
测试截图:
- 继承的父类、子类
- 超类:被继承的类叫做超类(父类)。也就是已经存在的类且被定义在某个类的extends关键词后面的类叫做父类
- 子类:继承的类叫做子类(基类)。也就是通过超类派生的类
- 继承的权限
- 被private修饰的成员方法和成员变量不能被继承
- 被public,protected和默认修饰的成员方法和成员变量能被继承
- 通过继承子类可以得到超类的非private修饰的方法,如上面Code中的:dog.eat();
在Dog类中并没有eat()方法,但是却可以调用,是因为Dog继承自Animal,得到了Animal的eat()方法
- 通过继承也可以得到超类非private修饰的成员变量
- super关键字 :和this相对,this表示本身对象,而super则是代表超类对象。
public Dog() {
super(); //调用父类的构造
}
public void sleep() {
System.out.println("狗睡觉...(子类对父类的重写,验证方法 的多态)");
super.fly(); //调用父类的方法
}
- super和this的总结:
- this的三个用途:
- 引用隐式参数
- 调用该类的其他构造器
public Dog() {
this("this测试");
}
public Dog(String name) {
super();
this.name = name;
}
- 调用该类的方法
- super的两个用途:
- 调用超类的方法
- 调用超类的构造器
- 如果子类没有显示的调用超类的构造器,则将自动调用超类的默认构造器。如果超类没有不带参数的构造器,并且子类构造器中由没有显示的调用超类的其他构造,那么Java编译器将报错。
- 继承层次:
对于上面的程序示例,Animal派生Mammal,Mammal派生Dog和Cat,这些继承关系之间就组成了一个层次关系。
由一个公共超类派生出的所有类的集合被称为继承层次。在继承层次中,从某个特定的类到其祖先的路径被称为继承链。
图解:
二、多态和重写(覆盖)
多态是对象采取多种形式表现的能力。当一个父类引用是用来指向一个子类对象时,在通过父类对象去调用子类的方法,就是一个多态表现。
- 多态存在的条件
- 继承:多态的存在必须要继承
- 重写父类方法:除了继承外,多态还要重写父类的方法
- 多态是什么?
多态是指当父类和子类都有同样的方法的时候,且父类对象变量引用了子类的对象,那么在调用的时候,就会动态的绑定到具体的子类,然后在调用子类的这个方法,而不是因为是父类的对象变量就调用父类的方法。
所以有了a)的两点条件,解释一下:
- 继承:因为要父类对象去引用子类的对象,所以要有继承
- 重写:因为要有和父类同样的方法,那么这个方法就是继承去的,所 以为了体现不同,最好重写,不然这种多态是无意义的。
- 多态的实现机制:动态绑定(下面介绍)
- 多态的三点重点:
成员变量的多态:编译看左边(看父类),运行看左边(看父类), 所以调用的还是父类的成员对象。
静态方法的多态:编译看左边(看父类),运行看左边(看父类), 所以调用的还是父类的静态方法。
成员方法的多态:编译看左边(看父类),运行看右边(看子类), 所以调用的是子类的成员方法。
- 构造方法的调用:
在创建子类对象的时候,同时还会调用父类的构造方法,对父类数据进行初始化。
- 多态的优点
- 提高了代码的维护性
- 提高了代码的扩展性
三、绑定
程序绑定的概念:绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定
- 静态绑定
在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现。例如:C。针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定
- 动态绑定
后期绑定:在运行时根据具体对象的类型进行绑定。若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的。但我们至少可以这样认为:它们都要在对象中安插某些特殊类型的信息。
动态绑定的过程:
1. 虚拟机提取对象的实际类型的方法表;
2. 虚拟机搜索方法签名;
3. 调用方法。
四、阻止继承
在实际的开发中可能不允许某个类定义子类,那么这种类叫做最终类或者叫做final类。但这个final类如何实现呢?见下代码就是一个final类:
final public class Person extends Mammal{
private String name;
private String gender;
private int age;
public Person(){}
public Person(String name,String gender, int age){
super();
this.name = name;
this.age = age;
this.gender = gender;
}
....
}
扩展知识点:
- instanceof关键字
java中的instanceof运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
if (dog instanceof Animal) {
System.out.println("dog是Animal类的一个实例");
} else {
System.out.println("dog不是Animal类的一个实例");
}
if (animal instanceof Dog) {
System.out.println("animal是Dog类的一个实例");
} else {
System.out.println("animal不是Dog类的一个实例");
}
当将超类转成子类之前一定要使用instanceof对子类对象进行检查。如下代码段:
Animal animal = new Dog();
if (animal instanceof Dog) {
Dog dog = (Dog)animal;
System.out.println("animal是Dog类的一个实例,可以转 换");
}else {
System.out.println("animal不是Dog类的一个实例");
}
- 受保护的访问
受保护的访问就是对protected修饰的方法和成员变量的访问。访问权限见总结12
- final修饰符(重点)
- final修饰变量:那么变量变为常量,在赋初值之后,值不可以在改变
- final修饰类:那么类就变为最终类,不可在派生子类
- final修饰方法:则该方法可以被继承,但是不可以被重写。
- final修饰对象:那么对象的引用不可再变,但是引用对象的值是可以变的。(就 是说对象被final修饰后,就不能在指向其他的对象,但是对 象中存储的值是可以变的)
以上是关于继承简介的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向Linux 文件权限 ( Linux 权限简介 | 系统权限 | 用户权限 | 匿名用户权限 | 读 | 写 | 执行 | 更改组 | 更改用户 | 粘滞 )(代码片段
SpringCloud系列十一:SpringCloudStream(SpringCloudStream 简介创建消息生产者创建消息消费者自定义消息通道分组与持久化设置 RoutingKey)(代码片段
C#-WebForm-★内置对象简介★Request-获取请求对象Response相应请求对象Session全局变量(私有)Cookie全局变量(私有)Application全局公共变量Vi(代码片段