当前位置: 首页 > news >正文

Java基础语法(八)| 继承

1. 继承

  • 继承概述

在面向对象里面,继承是对上一章的类,进一步抽象的过程。

​当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,这个类就是父类,那么多个子类无需再定义这些属性和行为,只要 继承那一个类(父类)即可。

其中,多个类可以称为子类,单独那一个类称为父类超类(superclass)或者基类

  • 继承概念

继承:就是子类继承父类的属性行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。

  • 继承的特点
  • 子类自动拥有父类非私有的成员(成员变量、成员方法)

  • 子类也可以拥有自己的成员

  •  继承的好处
  • 提高代码的复用性,降低重复代码;

  • 由于有了继承,类与类之间产生了关系,是多态的基础。

  • 继承的格式
class 父类 { ... }
class 子类 extends 父类 { ... }
  • 代码示例:
//父类
public class Person {public void eat(){System.out.println("吃饭");}public void sleep(){System.out.println("睡觉");}
}//子类
public class Student extends Person { }
//子类
public class Teacher extends Person { }/** 定义测试类*/
public class PersonTest {public static void main(String[] args) {        Student s = new Student();s.eat();s.sleep();Teacher t = new Teacher();t.eat();t.sleep();}
}
  •  继承中成员访问的特点

  子类访问父类非私有成员:

public class Father {//私有的成员变量private int num = 10;public int num2 = 20;//私有的成员方法private void mothod(){System.out.println(num);System.out.println(num2);}public void show(){System.out.println(num);System.out.println(num2);}
}public class Son extends Father {//子类也可以有自己的东西public void function(){//子类不能访问父类中私有的成员变量// System.out.println(num);System.out.println(num2);}
}public class SonTest {public static void main(String[] args) {Son s = new Son();// s.num =200; //子类不能访问父类中的私有的成员变量s.num2 = 100;// s.mothod(); //子类不能访问父类中的私有的成员方法s.function(); //也可以访问自己的方法s.show();}
}

2. 成员变量

 2.1 成员变量不重名

如果子类父类中出现不重名的成员变量,这时的访问是没有影响的。

代码示例:

//父类
public class Father {int num = 10;
}//子类
public class Son extends Father {//子类成员变量int num2 = 20;//子类成员方法public void function(){// 访问父类中的num,System.out.println("Fu num="+num); //10    // 访问子类中的num2System.out.println("Zi num2="+num2); // 20}
}//测试类
public class SonTest {public static void main(String[] args) {Son s = new Son();s.function();}
}

2.2 成员变量重名

如果子类父类中出现重名的成员变量,这时的访问是有影响的。

 代码示例:

//父类
public class Father {int num = 10;
}//子类
public class Son extends Father {int num = 20;//子类成员方法public void function(){//如果子类成员变量的名与父类成中变量名一样,就近原则System.out.println("num="+num); //20    }
}//测试
public class SonTest {public static void main(String[] args) {Son s = new Son();s.function();}
}

2.3 super关键字 

子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用super关键字,修饰父类成员变量。

  • 使用格式

 【super.父类成员变量名】

 代码示例:

public class Son extends Father {int num = 20;//子类成员方法public void function(){//如果子类成员变量的名与父类成中变量名一样,就近原则// System.out.println("Fu num="+num); //20    //我就想访问父类中的成员变量,怎么办?  用superSystem.out.println(super.num);//此时访问的就是父类的成员变量 10}
}

注意:

Fu类中的成员变量是非私有的,子类中可以直接访问。若Fu类中的成员变量私有了,子类是不能直接访问的。

通常编码时,我们遵循封装的原则,

使用private修饰成员变量,那么如何访问父类的私有成员变量呢?----可以在父类中提供公共的getXxx方法和setXxx方法。

3. 成员方法

3.1 成员方法不重名

如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。

代码示例:

//父类
public class Father {public void show(){System.out.println("我是父类Father");}
}//子类
public class Son extends Father {public void show2(){System.out.println("我是子类Father");}
}//测试
public class SonTest {public static void main(String[] args) {Son s = new Son();s.show();//调用父类方法s.show2();//调用子类方法}
}

3.2 方法重写

 如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做 方法重写(Override)。

  • 什么是方法的重写 

方法重写:子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。

代码示例:

//父类
public class Father {public void show(){System.out.println("我是父类Father");}public void method(){System.out.println("我是父类method");}
}
//子类
public class Son extends Father {public void show2(){System.out.println("我是子类Father");}public void method(){System.out.println("我是子x`类method");}
}//测试
public class SonTest {public static void main(String[] args) {Son s = new Son();s.show();//调用父类方法s.show2();//调用子类方法System.out.println("===================");//方法重写:子类中出现了与父类中的一模一样的方法//子类重写了父类的方法s.method();}
}
  •  方法重写的应用场景

子类可以根据需要,定义特定于自己的行为。既沿袭了父类的功能名称,又根据子类的需要重新实现父类方法,从而进行扩展增强。

 代码示例:

class Phone {public void sendMessage(){System.out.println("发短信");}public void call(){System.out.println("打电话");}public void showNum(){System.out.println("来电显示号码");    }
}//智能手机类
class NewPhone extends Phone {//重写父类的来电显示号码功能,并增加自己的显示姓名和图片功能   public void showNum(){        //调用父类已经存在的功能使用supersuper.showNum();//增加自己特有显示姓名和图片功能System.out.println("显示来电姓名");System.out.println("显示头像");}
}public class ExtendsDemo06 {public static void main(String[] args) {// 创建子类对象NewPhone np = new NewPhone();// 调用父类继承而来的方法np.call();// 调用子类重写的方法np.showNum();}
}
  •  方法重写的注意事项

1. 子类方法重写父类方法,必须要保证权限大于等于父类权限,最好修饰权限一样。
2. 子类方法重写父类方法,返回值类型、方法名和参数列表都要一模一样。

4. 构造方法

1.构造方法的名字是与类名一致的。所有子类是无法继承父类构造方法的。

2.构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个super() , 表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。

代码示例:

//父类
public class Father {private int num;//父类的构造方法public Father(){System.out.println("父类的构造方法");}public Father(int num) {this.num = num;}public void show1(){System.out.println(num);}
}//子类
public class Son extends Father {//子类无参构造方法public Son(){// 子类构造方法中的第一行默认有 super() ,给父类进行初始化的// 作用:因为继承必须先调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。super();System.out.println("子类的构造方法");}//子类有参构造方法public Son(int num2) {super(34);this.num2 = num2;}public void show2(){System.out.println(num2);}    
}//测试
public class Test {public static void main(String[] args) {//在每次创建子类对象时,都会先初始化父类构造方法,再创建其子类对象本身。Son s = new Son();Son s = new Son();//每一次实例子类对象,都会先访问父类的无参构造  (这里两次)//访问有参构造Son s = new Son(2000);s.show1();s.show2();}
}

在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造方法调用时,一定先调用父类的构造方法。

  •  访问构造方法的注意事项:

* 在子类构造方法中的第一行默认有 super() ,给父类进行初始化的
    * 在子类构造方法中可以手动调用父类其他重载的构造方法
       格式: super(参数列表);
* super 是写在子类的构造方法的第一行。

【注意】

【super.父类成员方法】,表示调用父类的成员方法

【super.父类成员变量名】,表示调用父类的成员变量

【super()】,表示访问父类中的无参构造

【super( 88 )】, 表示访问父类中的有参构造

5. super和this

  • super和this的含义
  • ==super:前提:继承关系 。 代表父类的存储空间标识(可以理解为父亲的引用)。

  • ==this:代表当前对象的引用(谁调用就代表谁)

super和this的用法


  •  访问成员

this.成员变量       ‐‐    本类的
this.成员方法名()    ‐‐    本类的    
    
super.成员变量      ‐‐    父类的
super.成员方法名()   ‐‐    父类的

代码示例:

class Animal {public void eat() {System.out.println("animal : eat");    }
}class Cat extends Animal {public void eat() {System.out.println("cat : eat");}public void eatTest() {this.eat();   // this  调用本类的方法        super.eat();  // super 调用父类的方法    }}public class ExtendsDemo08 {public static void main(String[] args) {        Animal a = new Animal();a.eat();Cat c = new Cat();c.eatTest();}}
  • 访问构造

 this(...)       ‐‐    本类的构造方法
super(...)      ‐‐    父类的构造方法

【注意】

子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。

super()和this()都必须是在构造方法的第一行,所以不能同时出现。

6. 继承的特点

/*
    Java中继承的特点:
        A:Java只支持单继承,不支持多继承。            
        B:Java支持多层继承(继承体系),间接继承
*/

class Father(){}
class Mother(){}

class son extends Father(){} // 正确
class son2 extends Father , Mother {} // 不正确

  •  Java只支持单继承,不支持多继承

//一个类只能有一个父类,不可以有多个父类。
class C extends A{}     //ok
class C extends A,B...  //error

  •  Java支持多层继承(继承体系)
class A{}
class B extends A{}
class C extends B{}
  •  子类和父类是一种相对的概念,一个父类可以有很多个子类
class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
class Pig extends Animal{}

代码示例:

//爷爷
public class GrandFather {public void show(){System.out.println("爷爷");}
}
//父亲
public class Father extends GrandFather {public void method(){System.out.println("父亲");}
}
//儿子
public class Son extends Father { }//测试
public class Test {public static void main(String[] args) {Son s = new Son();s.show();// 间接的继承爷爷的方法s.method();//继承了父亲的方法}
}

相关文章:

  • 基于Hive的天气情况大数据分析系统(通过hive进行大数据分析将分析的数据通过sqoop导入到mysql,通过Django基于mysql的数据做可视化)
  • ArcGIS矢量裁剪矢量
  • SpringBoot --条件注解与属性绑定
  • Contos7 安装 Maven
  • sqlite3的安装
  • 前端Ajax请求从后端获取二进制文件并下载
  • STM32学习笔记(9_2)- USART串口外设
  • qt学习第三天,qt设计师的第一个简单案例
  • JVM(一)——内存结构
  • 实验十 枚举问题(过程模拟)
  • 正则表达式 vs. 字符串处理:解析优势与劣势
  • [linux][调度] 内核抢占入门 —— 高优先级线程被唤醒时会立即抢占当前线程吗 ?
  • PCM /G711音频播放器 :Audacity
  • js 分割号查找内容
  • Unity 镜头动画
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • 4. 路由到控制器 - Laravel从零开始教程
  • angular组件开发
  • Bytom交易说明(账户管理模式)
  • CSS居中完全指南——构建CSS居中决策树
  • Hibernate最全面试题
  • HomeBrew常规使用教程
  • Javascript弹出层-初探
  • rc-form之最单纯情况
  • SegmentFault 2015 Top Rank
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • SpriteKit 技巧之添加背景图片
  • 免费小说阅读小程序
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 思否第一天
  • 因为阿里,他们成了“杭漂”
  • Semaphore
  • 树莓派用上kodexplorer也能玩成私有网盘
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • (26)4.7 字符函数和字符串函数
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (k8s中)docker netty OOM问题记录
  • (编译到47%失败)to be deleted
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (南京观海微电子)——I3C协议介绍
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (五)MySQL的备份及恢复
  • (一)Linux+Windows下安装ffmpeg
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET CORE 第一节 创建基本的 asp.net core
  • .net分布式压力测试工具(Beetle.DT)
  • .Net中的设计模式——Factory Method模式
  • /var/spool/postfix/maildrop 下有大量文件
  • ?php echo $logosrc[0];?,如何在一行中显示logo和标题?
  • @Conditional注解详解
  • [ai笔记9] openAI Sora技术文档引用文献汇总
  • [Asp.net mvc]国际化
  • [C/C++]数据结构----顺序表的实现(增删查改)