继承性的主要目的,继承的实现,继承的限制
        
        继承是面向对象中的第二大主要特点,其核心的本质在于:可以将父类的功能一直沿用下去
        
        为什么需要继承?
            那么为了更好的区分出之前学习的概念与现在程序的区别,下面通过两个具体的代码来进行研究
            例如:现在有俩个类:Person,Student,按照原始的方式,程序代码实现如下:

class Person{
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
class Student{
private String name;
private int age;
private String school;
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public void setSchool(String school){
this.school = school;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public String getSchool(){
return this.school;
}
}
public class inherit{
public static void main(String args[]){
System.out.println();
}
}               

两个类出现有重复,而且最为关键的问题是学生从现实的角度来看一定是个人
                那么按照这样的理解就可以发现出现重复的核心问题所在了,就是两个类之间没有联系
                之前所编写的代码或者说之前所学习到的概念那么还不足以解决多个类之间的代码重复消除问题
Student 是比 Person 更加细化的定义范畴
                
        使用继承解决问题
            在java中可以利用继承的概念来实现父类代码的重用问题,程序中可以使用extennds 关键字实现继承操作的定义
            其使用的语法如下:
            class 子类 extends 父类{}
            需要注意点名词概念:
                子类:也被称为派生类
                extends虽然从本质上来讲属于继承概念,但是其翻译为扩展,扩充的意思
                父类 本质上在java中称为超类(Super Class)
            
            范例:继承的基本使用

class Person{
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
class Student extends Person{ // Student 是Person 的子类
// 此时并没有在Student类里面定义任何的操作
}
public class inherit{
public static void main(String args[]){
Student stu = new Student();// 实例化子类对象
stu.setName("少爷");//通过Person类继承而来
stu.setAge(20);//通过Person类继承而来
System.out.println("姓名:"+stu.getName+",年龄:"+stu.getAge());
}
}
/*
结果
姓名:少爷,年龄:20
*/               

通过以上的程序就可以发现一点:子类在继承了父类之中,那么对于父类的支持方法不会减少
                但是子类可以进一步扩充属于自己的属性与方法
                
                范例:继承的基本使用

class Person{
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
class Student extends Person{ // Student 是Person 的子类
private String school; // 子类自己扩充的属性
public void setSchool(String school){
this.school = school;
}
public String getSchool(){
return this.school;
}
public class inherit{
public static void main(String args[]){
Student stu = new Student();// 实例化子类对象
stu.setName("少爷");//通过Person类继承而来
stu.setAge(20);//通过Person类继承而来
stu.setSchool("清华");//子类自己扩充的属性
System.out.println("姓名:"+stu.getName+",年龄:"+stu.getAge()+",学校:"+stu.getSchool());
}
}
/*
结果
姓名:少爷,年龄:20,学校:五道口
*/           

通过这样的继承实现发现:
                    父类的功能可以延续到子类继续使用,这样在某些父类不能够修改的情况下,就可以通过继承来实现功能的扩充
                    子类中至少可以维持父类的原始方法不变,也就是说在子类里面父类的方法功能不会减少
                
*/

/*    继承的使用限制
        虽然继承的核心目的在于扩充类中的已有功能,但是在实际的开发之中,继承的使用也是存在有诺干限制的,这些限制必须注意
        限制一:java不允许多重继承,也就是说一个子类只能够继承一个父类
                因为C++它支持多继承,也就是说一个子类可以同时继承多个父类
            范例:错误代码

class A{

}
class B{ }
class C extendsa A,B{ }
public class inherit{
public static void main(String args[]){
System.out.println();
}
}                   

那么为什么实际中会出现这种代码呢?
                其实本质上也只是希望C类可以同时继承A,B类的方法,但是由于这样的做法与现实生活有冲突,所以从java的角度就屏蔽了,但是有解决方案
                虽然java不允许多重继承,但是却允许多层继承,以下代码为方案:

class A{

}
class Bextendsa A{ }
class C extendsa B{ }
public class inherit{
public static void main(String args[]){
System.out.println();
}
}               

此时的C类实际上就具备有A,B类的全部定义,但是从实际的开发,这种继承的层次关系不要超过三层
                
        限制二:子类在继承父类之后会将父类中的全部结构继承下来,但是对于私有的操作属于隐式继承(子类不能直接调用),而所有的非私有操作属于显式继承(可以直接调用)
            范例:观察显式继承

class A{
private String name:
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
class B extendsa A{ }
public class inherit{
public static void main(String args[]){
B b= new B();
b.setName("少爷");
System.out.println(b.getName());
}
}

现在对于子类B而言是存在name属性的,但是这个属性子类并不能够直接操作
                范例:子类B直接访问

class A{
private String name:
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
class B extendsa A{
public void print(){
System.out.println(name);
}
}
public class inherit{
public static void main(String args[]){
B b= new B();
b.setName("少爷");
System.out.println(b.getName());
}
}//结果程序出错                   

也就是说此时的name属于隐式继承,而所有的setter方法属于显式继承,显式继承可以直接调用,而隐式继承的只能够间接的操作或者不能够操作
                    
        限制三:在实例化子类对象时会默认调用子类的无参构造方法,但是在执行子类构造前会首先自动实例化父类构造为父类的对象实例化,也就是说父类对象永远早于子类对象的实例化
            范例:观察实例化过程

class A{
public A(){
System.out.println("***********************");
}
}
class B extends A{
public B(){
System.out.println("###########################");
}
}
public class inherit{
public static void main(String args[]){
B b= new B();
}
}
/*
结果:
***********************
###########################
*/               

如果说现在非要为子类加上一个调用父类构造的标记,那么就可以使用“super()”的形式完成

class A{
public A(){
System.out.println("***********************");
}
}
class B extends A{
public B(){
super(); // 表示由子类构造调用父类构造
System.out.println("###########################");
}
}
public class inherit{
public static void main(String args[]){
B b= new B();
}
}
/*
结果:
***********************
###########################
*/               

也就是证明,在子类的构造之中其实一直隐藏了一行“super()”语句,但是在进行无参父类构造调用的时候,写上“super()”是没有意义的
                往往是在父类没有提供无参构造时使用的
                范例:错误代码

class A{
public A(String name){
System.out.println("***********************");
}
}
class B extends A{
public B(){
// super(); // 表示由子类构造调用父类构造
System.out.println("###########################");
}
}
public class inherit{
public static void main(String args[]){
B b= new B();
}
}//结果程序出错                   

这个时候很明显使用隐含的“super()”并不合适,所以应该明确的调用指定参数的构造方法

class A{
public A(String name){
System.out.println("***********************");
}
}
class B extends A{
public B(String name){
super(name); // 表示由子类构造调用父类构造
System.out.println("###########################");
}
}
public class inherit{
public static void main(String args[]){
B b= new B("少爷");
}
}                   

在大多数情况下父类一般都会提供有无参构造方法,这个时候可以在子类构造中不出现“super()”的语句
                但是如果此时父类没有提供无参构造方法,那么子类就必须使用“super()”调用指定参数的构造方法

对于 super 调用构造方法的情况需要注意如下几项:
                    不管你子类怎么折腾都一定要去调用父类的构造方法,即:调用父类构造使用 super()
                    super() 是在子类中编写的,表示通过子类的构造方法去调用父类构造,必须放在子类构造方法的首行,不能与“this()”不能同时出现在构造方法之中,两者关系属于二选一
                    如果现在父类中没有提供无参构造方法,那么在子类构造之中必须明确的调用有参构造方法,必须使用 super 调用指定参数的父类构造
                    
                    this 是应用在本类的关键字,而 super 是应用在子类中的关键字,利用 super 找到父类结构

                分析:关于this()与super()的问题
                    在之前学习过this()表示调用本类的其他构造方法,而现在有了继承关系之后,可以使用super() 由子类调用父类中指定的构造方法,并且这两个语句都一定要出现在首行,也就是说这两个语句不能同时出现
                    
                范例:不让子类调用父类的构造

class A{
public A(String name){
System.out.println("***********************");
}
}
class B extends A{
public B(){ }
public B(String name){
this();//
System.out.println("###########################");
}
}
public class inherit{
public static void main(String args[]){
B b= new B("少爷");
}
}                   

在子类的构造方法中出现了“this()”,这样就不会出现“super()”的默认执行而转为调用本类的构造方法了
                那么这样是不是可以不调用父类构造了呢?
                
        总结
            1.继承的唯一好处就是进行了功能的扩充,并且java只支持单继承局限
            2.子类对象实例化时一定要先实例化父类对象,而后在实例化子类自己的对象

*/

菜鸡的Java笔记 第十九 - java 继承的更多相关文章

  1. 菜鸡的Java笔记 第二十九 - java 单例设计模式

    SingleCase 单例设计模式        1.单例设计模式的特点        2.多例设计模式的特点    内容    单例设计模式        现在如果说有这么一个程序类 class S ...

  2. Java进阶(三十九)Java集合类的排序,查找,替换操作

    Java进阶(三十九)Java集合类的排序,查找,替换操作 前言 在Java方向校招过程中,经常会遇到将输入转换为数组的情况,而我们通常使用ArrayList来表示动态数组.获取到ArrayList对 ...

  3. 菜鸡的Java笔记 第二十八 - java 包的定义

    包的主要作用以及定义    包的导入操作    系统常见的开发包    jar 程序命令        包的定义        在任何的操作系统之中都有一个统一的共识:同一个目录下不能够存在有相同的文 ...

  4. Java笔记(二十九)……网络编程

    概述 网络模型 网络通讯的要素 ip地址:网络中设备的标识符 端口:用于标识同一台设备上不同的进程,有效端口:0~65535,其中0~1024是系统使用端口或者保留端口 TCP与UDP UDP特点: ...

  5. 菜鸡的Java笔记 第二十六 - java 内部类

    /*    innerClass        从实际的开发来看,真正写到内部类的时候是在很久以后了,短期内如果是自己编写代码,几乎是见不到内部类出现的        讲解它的目的第一个是为了解释概念 ...

  6. 菜鸡的Java笔记 第二十四 - java 接口的基本定义

    1.接口的基本定义以及使用形式        2.与接口有关的设计模式的初步认识        3.接口与抽象类的区别                 接口与抽象类相比,接口的使用几率是最高的,所有的 ...

  7. 菜鸡的Java笔记 第二十二 - java 对象多态性

    本次只是围绕着多态性的概念来进行讲解,但是所讲解的代码与实际的开发几乎没有关系,而且多态一定是在继承性的基础上才可以操作的,        而本次将使用类继承的关系来描述多态的性质,实际的开发中不会出 ...

  8. 菜鸡的Java笔记 第十八 - java 代码块

    代码块  code block                content (内容)        在程序结构之中使用"{}"定义的内容就称为代码块,但是会根据其声明的位置以及关 ...

  9. 菜鸡的Java笔记 第十六 - java 引用传递

    referenceDelivery    引用传递是整个java 的精髓,也是所有初学者最难学的地方        引用的本质:同一块堆内存可以被不同的栈内存所指向    下面通过三道程序来进行引用传 ...

随机推荐

  1. hexo配合github action 自动构建(多种形式)

    已经使用HEXO正常构建GitHub页面 根据github action 给hexo配置自动部署github page 前往墨抒颖的个人网站查看纯净版 1. 为仓库设置访问密钥 第一步先生成密钥,打开 ...

  2. C++学习笔记:09 函数模板与类模板

    课程<C++语言程序设计进阶>清华大学 郑莉老师) 引入 考虑一个求绝对值函数myabs,对于int,double,float等数据类型需要重载多次,编写多个函数体.函数体逻辑代码完全一致 ...

  3. 如何在 Serverless K8s 集群中低成本运行 Spark 数据计算?

    作者 | 柳密 阿里巴巴阿里云智能 ** 本文整理自<Serverless 技术公开课>,关注"Serverless"公众号,回复"入门",即可获取 ...

  4. Mydoom样本分析报告

    文件检测 信息 值 文件名 1.virus 文件类型 WIN 32 EXE 文件大小 41664 bytes MD5 3d466b0f8ba9f3fe03e137a34d79f682 SHA-256 ...

  5. 零基础学习Linux必会的60个常用命令

    Linux必学的60个命令Linux提供了大量的命令,利用它可以有效地完成大量的工 作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在Linux系统上工作离不开使用系统提供的命令. ...

  6. 攻防世界 杂项 10.2017_Dating_in_Singapore

    题目描述: 01081522291516170310172431-050607132027262728-0102030209162330-02091623020310090910172423-0201 ...

  7. hdu 2830 Matrix Swapping II(额,,排序?)

    题意: N*M的矩阵,每个格中不是0就是1. 可以任意交换某两列.最后得到一个新矩阵. 问可以得到的最大的子矩形面积是多少(这个子矩形必须全是1). 思路: 先统计,a[i][j]记录从第i行第j列格 ...

  8. dns+nginx实现多虚拟主机

    借鉴于朋友的需求,公司需要启用域名访问内部的业务系统,现实情况是内部的业务系统目前使用的是单主机,单nginx多端口的方式再运行,朋友最终想实现启用域名方式问题,且域名不需要用户手工输入端口号 两种思 ...

  9. sqlldr导入报错:field in data file exceeds maximum length

    检查报错日志提示:field in data file exceeds maximum length REMARK字段设置:varchar2(2000),报错的内容也没有超1000个字符 表中定义的字 ...

  10. 【mysql1】如何删除MySQL内存|不再跟新系列

    完全卸载mysql的具体步骤: 包括停止服务  +  卸载相关程序  +  删除注册表等等 步骤一:  windows键+R-->Control-->程序和功能:所有MySQL程序点击右键 ...