带你玩转java封装和继承(上)

news2024/9/24 17:36:59

上次带大家学习了java里面比较重要的知识点类和对象,而且我们知道java是一门面向对象的语言,有时一个程序里可能有很多类,那么这么多类他们之间有什么联系吗?今天就带大家学习一下java类之间的关系。

 

 什么是继承:

我们在日常学习中,在java程序编写时,先创建类,在实例化对象进一步对类进行使用,然而,世界上很多事物往往都不是独立的,他们之间可能存在着千丝万缕的联系,那么如何建立这种联系呢

举个例子创建一个狗类:

//Dog类
public class Dog{
  String name;
  String sex;
  int age;
    public void bark(){
      System.out.println(name+"正在汪汪汪");
   }
   public void sleep(){
      System.out.println(name+"正在睡觉")
   }
}

在定义一个猫类:

public class Cat{
string name;
int age;
string color;
public void sleep()
{
System.out.println(name + "正在睡觉");
}
void mew(){
System.out.println(name + "喵喵喵~~~");
}
}

通过这两个例子我们可以很直观的看到,这两类有太多一样的地方,我们如果可以把这些一样的部分抽离出来,使用时直接调用它,代码效率会大大加强,实现了代码的复用,其实,这就是继承的本质。

继承 (inheritance) 机制 :是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性 的基础上进行扩展,增加新功能 ,这样产生新的类,称 派生类 。继承呈现了面向对象程序设计的层次结构, 体现了 由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码用
例如:狗和猫都是动物,那么我们就可以将共性的内容进行抽取,然后采用继承的思想来达到共用。
概念可能不太直观,这里我以上面为例,重新写一段程序:

 

public class Animal{
   String name;
   int age;
  public void eat(){
    System.out.println(name+"正在吃饭");
  }
  public void sleep(){
    System.out.println(name+"正在睡觉");
  }
}
public class Dog extends Animal{
  void bark(){
    System.out.println(name + "汪汪汪~~~");
  }
}
public class Cat extends Animal{
  void mew(){
    System.out.println(name + "喵喵喵~~~");
 }
}

       我们将Dog类和Cat类称为子类,Animal为父类。 

       这样的话,代码就大大简化当我们再去创建动物对象时,就可以直接调用这里的Animal类中的成员这里的extends是子类继承父类成员时必须使用的关键字。

子类如何访问父类的成员:

子类访问父类的成员,这里分为两种情况:

  1. 子类成员与父类成员名字一致。
  2. 子类成员与父类成员名字不一致。

 子类成员与父类成员名字一致

public class Base {
int a;
int b;
int c;
}
/
public class Derived extends Base{
int a; // 与父类中成员a同名,且类型相同
char b; // 与父类中成员b同名,但类型不同
public void method(){
a = 100; // 访问父类继承的a,还是子类自己新增的a?
b = 101; // 访问父类继承的b,还是子类自己新增的b?
c = 102; // 子类没有c,访问的肯定是从父类继承下来的c
// d = 103; // 编译失败,因为父类和子类都没有定义成员变量b
}
}

这里需要注意的是:

  1. 当父类与子类成员名字一致时,优先访问自己的成员变量。
  2. 当访问成员变量时优先访问自己的,若没有再去访问父类的
  3. 若子类与父类都没有,会发生编译错误。

成员变量是这样,成员方法也是这样,调用成员方法时优先考虑子类自己的,若没有则去父类中查找,都没有就会报错。

public class Base {
public void ways1(){
System.out.println("Base中的ways1()");
}
public void ways2(){
System.out.println("Base中的ways2()");
}
}
public class Derived extends Base{
public void ways1(int a) {
System.out.println("Derived中的way1(int)方法");
}
public void ways2(){
System.out.println("Derived中的ways2()方法");
}
public void ways3(){
ways1(); // 调用的是父类中的因为,父类中午参数
ways1(20); // 传递参数,访问子类中的way1(int)
ways2(); //默认访问子类中的ways2
}
}

 super关键字

上面我们说了,当访问的成员或变量子类与父类同名时,默认访问的是子类的,那么如果就像访问父类的呢?这里就需要使用到super关键字了。他可以在子类方法中访问父类的成员

 

class Country {
    String name;
    void value() {
       name = "China";
    }
}
  
class City extends Country {
    String name;
    void value() {
    name = "Shanghai";
    super.value();      //调用父类的方法
    System.out.println(name);   //默认打印子类中的china
    System.out.println(super.name);   //使用super关键字调用父类中的name
    }
  
    public static void main(String[] args) {
       City c=new City();
       c.value();
       }
}

运行结果: Shanghai     China   

在子类方法中,如果想要明确访问父类中成员时,借助super关键字即可。
注意:
  1. super关键字只可以在非静态的方法中访问。
  2. super关键字是在子类中调用父类成员使用的。

子类的构造方法

我们在实例化子类对象时,会调用子类的构造方法,然而其实子类的构造方法在调用之前,编译器已经偷偷地将父类的构造方法调用过一次了,只是没有显示而已,我们可以这样理解,子类中的成员变量,其实是由两部分构成的,一部分是自己的,另一部分是从父类中继承下来的,所以必须先要把从父类中继承的成员变量初始化了,然后才初始化自己的成员变量。

正所谓:父子父子,先有父才能有子。

public class Base {
public Base(){
System.out.println("Base()");
}
}
public class Derived extends Base{
public Derived(){
// super(); 
System.out.println("Derived()");
}
}
public class Test {
public static void main(String[] args) {
Derived d = new Derived();
}
}

运行结果:Base()   Derived()

总结:

  1. 当父类中显式定义无参或者默认的构造方法,那么在子类中都默认调用了父类无参数的构造方法。
  2. 当自行定义有参数的父类构造方法时,子类的构造方法中不在默认提供调用父类构造方法的操作。需要用户在子类的构造方法中自行调用,否则编译错误。
  3. 当在子类中调用super(),必须将super()放到第一行,否则编译错误。
  4. 在子类的构造方法中不能同时出现super()和this因为从语法上他们都要放到第一行。

 super和this的区别

这里提醒一下,不懂this的uu们,看我的上一篇文章。

this 相当于是指向当前对象本身,可以理解为指向当前对象的指针,(当然java中没有指针只是这样方便理解)。

这里介绍this的几种用法:

  1. .普通的直接引用:直接使用this.×××来引用
  2. 当类中的成员变量与成员函数中的参数同名时,this.成员变量,用来指代当前对象的引用
    class Person {
        private int age = 10;
        public Person(){
        System.out.println("初始化年龄:"+age);
    }
        public int GetAge(int age){
            this.age = age;   //调用的是当前对象Harry的age=形参的age
            return this.age;
        }
    }
     
    public class test1 {
        public static void main(String[] args) {
            Person Harry = new Person();
            System.out.println("Harry's age is "+Harry.GetAge(12));
        }
    }
  3. 用来调用另一种构造方法:
    
        
    public class Chinese { 
        Chinese() { 
          
           System.out.println("无参数构造方法"": "+"A chinese coder."); 
        } 
        
        Chinese(String name) { 
          
           System.out.println("含一个参数的构造方法"": "+"his name is " + name); 
        } 
        
        Chinese(String name, int age) { 
           this(name);// 调用具有相同形参的构造方法(3) 
           System.out.println("两个形参的构造方法:his age is " + age); 
        } 
        
        public static void main(String[] args) { 
           Chinese cn = new Chinese(); 
           cn = new Chinese("codersai"); 
           cn = new Chinese("codersai", 18); 
        } 
    }

    super可以理解为一个指向父类对象的指针,完成对父类对象的引用。

    普通的直接引用:super.×××引用父类对象的成员变量

    子类中的成员变量或方法与父类中的成员变量或方法同名:使用super.×××来调用父类的成员。

    引用构造函数:子类中的构造方法执行之前要先调用父类中的super(),且必须是第一行。

初始化代码运行顺序

静态代码块执行    实例代码块执行       构造方法执行

这三种代码块的运行顺序是怎么样的呢,

class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Person:构造方法执行");
}
{
System.out.println("Person:实例代码块执行");
}
static {
System.out.println("Person:静态代码块执行");
}
}
class Student extends Person{
public Student(String name,int age) {
super(name,age);
System.out.println("Student:构造方法执行");
}
{
System.out.println("Student:实例代码块执行");
}
static {
System.out.println("Student:静态代码块执行");
}
}
public class TestDemo4 {
public static void main(String[] args) {
Student student1 = new Student("张三",19);
System.out.println("===========================");
Student student2 = new Student("ningzhiyuan",20);

运行结果:

Person :静态代码块执行
Student :静态代码块执行
Person :实例代码块执行
Person :构造方法执行
Student :实例代码块执行
Student :构造方法执行
===========================
Person :实例代码块执行
Person :构造方法执行
Student :实例代码块执行
Student :构造方法执行

       由此我们知道了代码块的执行顺序:父类静态代码块,子类静态方法,父类实例代码块 ,父类构造方法,子类实例代码块,子类构造方法。并且静态代码块只执行一次。

访问限定符

java中为了更好的封装,建立了访问限定符,让数据封装起来,数据更加安全。

 

这些限定符决定了数据在哪里可以使用,哪里不可以使用,对于数据权限的管理非常有效。也提醒我们后面使用数据之前应该了解数据的权限避免写出错误的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1483462.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

摄像机LookDirection参数对模型缩放灵敏度的影响

继续整上回的wpf 3d obj模型程序; 它用HelixToolKit加载了以后,默认可以用鼠标操作模型,中键缩放模型; 有的时候中键稍微滚动几下模型就不见了; 用不同的模型试了一下;中键缩放的灵敏度,就是…

FreeRTOS学习笔记-基于STM32(1)基础知识

一、裸机与RTOS 我们使用的32板子是裸机,又称前后台系统。裸机有如下缺点: 1、实时性差。只能一步一步执行任务,比如在一个while循环中,要想执行上一个任务,就必须把下面的任务执行完,循环一遍后才能执行…

BUGKU bp

打开环境,他提示了弱密码top1000,随便输入密码123抓包爆破 发现长度都一样,看一下响应发现一段js代码,若r值为{code: bugku10000},则会返回错误,通过这一句“window.location.href success.php?coder.cod…

StarRocks——Stream Load 事务接口实现原理

目录 前言 一、StarRocks 数据导入 二、StarRocks 事务写入原理 三、InLong 实时写入StarRocks原理 3.1 InLong概述 3.2 基本原理 3.3 详细流程 3.3.1 任务写入数据 3.3.2 任务保存检查点 3.3.3 任务如何确认保存点成功 3.3.4 任务如何初始化 3.4 Exactly Once 保证…

【MATLAB】 ICEEMDAN信号分解+FFT傅里叶频谱变换组合算法

有意向获取代码,请转文末观看代码获取方式~ 展示出图效果 1 ICEEMDAN信号分解算法 ICEEMDAN 分解又叫改进的自适应噪声完备集合经验模态分解,英文全称为 Improved Complete Ensemble Empirical Mode Decomposition with Adaptive Noise。 ICEEMDAN (I…

【书生·浦语大模型实战营】第 2 节 -课后作业

第二节 -轻松玩转书生浦语大模型趣味 Demo-课后作业 0.课程体验0.1 鸡兔同笼0.2 逻辑推理0.3 AI会毁灭人类吗? 1.课后作业1.1 基础作业1.1.1 作业11.1.2 作业2 0.课程体验 课程链接:https://github.com/internLM/tutorial 首先,这个课程是免费…

《Spring Security 简易速速上手小册》第7章 REST API 与微服务安全(2024 最新版)

文章目录 7.1 保护 REST API7.1.1 基础知识详解7.1.2 重点案例:使用 JWT 进行身份验证和授权案例 Demo 7.1.3 拓展案例 1:API 密钥认证案例 Demo测试API密钥认证 7.1.4 拓展案例 2:使用 OAuth2 保护 API案例 Demo测试 OAuth2 保护的 API 7.2 …

vue 之 Quill编辑器封装

安装 npm install vue-quill-editor --save <template><div><el-upload:action"uploadUrl":before-upload"handleBeforeUpload":on-success"handleUploadSuccess":on-error"handleUploadError"name"file":sh…

家政行业的数字转型:开发智能化家政预约APP的挑战与机遇

为了适应这一变化&#xff0c;许多家政企业开始积极探索数字化转型&#xff0c;其中包括开发智能化预约APP。本文将探讨开发智能化预约APP所面临的挑战与机遇。 ​一、挑战&#xff1a; 1.用户体验设计&#xff1a; -开发智能化预约APP需要注重用户体验设计&#xff0c;包括…

Pytest插件pytest-selenium-让自动化测试更简洁

在现代Web应用的开发中&#xff0c;自动化测试成为确保网站质量的重要手段之一。而Pytest插件 pytest-selenium 则为开发者提供了简单而强大的工具&#xff0c;以便于使用Python进行Web应用的自动化测试。本文将深入介绍 pytest-selenium 插件的基本用法和实际案例&#xff0c;…

Web Tomcat

目录 1 前言2 Tomcat的安装3 Tomcat文件的构成4 Tomcat的使用步骤 1 前言 Tomcat是一个 http(web)的容器&#xff0c;笼统的理解一下所有的网站都叫做web。这个web容器可以把我们的前端(htmlcssjs)和后端(servlet)代码都运行起来。 Tomcat是一个免费的开源的Servlet容器&#…

可视化场景(1):销售业绩大屏-是骡子是马,牵出溜溜

销售业绩可视化大屏的是一种有力的销售数据管理工具&#xff0c;贝格前端工场分享一批给友友们&#xff0c;如需要定制&#xff0c;可以与我们联络&#xff0c;开始了。 销售业绩可视化大屏是一种将销售数据以图表、数字、文字等形式展示在大屏幕上的数据可视化工具。它的作用主…

如何在OnlyFans付费订阅?

OnlyFans成立于2016年&#xff0c;允许内容创作者从用户那里获得资金&#xff0c;用户需要支付订阅费用才能查看他们的内容。它在多个领域受到欢迎&#xff0c;包括音乐、健身、摄影&#xff0c;以及某种内容创作。 如何在OnlyFans付费订阅&#xff1f; 我们订阅之前需要一张…

JOSEF约瑟 漏电继电器LLJ-400F 配套零序互感器φ100mm 50-500mA 0.1S 导轨安装

系列型号&#xff1a; LLJ-150F(S)漏电继电器 LLJ-160F(S)漏电继电器 LLJ-200F(S)漏电继电器 LLJ-250F(S)漏电继电器 LLJ-300F(S)漏电继电器 LLJ-320F(S)漏电继电器 LLJ-400F(S)漏电继电器 LLJ-500F(S)漏电继电器 LLJ-600F(S)漏电继电器 一、产品用途及特点 LLJ-FS系列漏电继电…

图表背后的智慧:办公场景中的数据可视化革新

在现代办公场景中&#xff0c;数据可视化的应用已经成为提高效率、推动创新的得力工具。无论是管理层还是普通员工&#xff0c;都能从数据可视化中受益匪浅。下面我就以可视化从业者的角度&#xff0c;简单聊聊这个话题。 首先&#xff0c;数据可视化提升了数据的易读性与理解性…

GitLab代码服务器搭建

在Ubuntu上搭建GitLab服务器需要按照一系列步骤进行操作。以下是一个基本的指南&#xff1a; 安装必要的依赖包&#xff1a;首先&#xff0c;确保系统已经安装了所需的依赖包。这通常包括curl、openssh-server、ca-certificates和postfix&#xff08;如果你打算使用GitLab的邮件…

985机械研一转码,java还是c++?

985机械研一转码&#xff0c;java还是c&#xff1f; 在开始前我分享下我的经历&#xff0c;我刚入行时遇到一个好公司和师父&#xff0c;给了我机会&#xff0c;一年时间从3k薪资涨到18k的&#xff0c; 我师父给了一些 电气工程师学习方法和资料&#xff0c;让我不断提升自己&…

初学Vue总结

0 Vue概述 问题&#xff1a;我们已经学过了htmlCssjavascript,可以开发前端页面了&#xff0c;但会发现&#xff0c;效率太低了。那么&#xff0c;有没有什么工具可以提高我们的开发效率&#xff0c;加快开发速度呢&#xff1f; 他来了&#xff0c;他来了&#xff0c;他大佬似…

总结一下linux性能检测和调优手段

1.perf 是 Linux 系统中性能分析工具&#xff0c;用于收集性能相关的信息。它可以用于查看 CPU 使用情况、内存性能、磁盘 I/O 等&#xff0c;以帮助开发者找到性能瓶颈。 以下是一些 perf 常见用法和示例&#xff1a; 1. CPU Profiling a. 查看 CPU 使用率 perf stat -e cpu…

一篇文章速通static关键字(JAVA)

目录 1.原理——内存机制 1.1 修饰对象 1.2 lifecycle生命周期 2. 静态属性&#xff08;类属性&#xff09;和实例属性&#xff08;对象属性&#xff09; 2.1 定义方式 2.2 调用方法 3. 静态方法和属性 3.1 在同一个类中 3.2 在不同类中 4.总结&#xff08;关键&#x…