「JavaSE」类和对象2

🎇个人主页:Ice_Sugar_7
🎇所属专栏:快来卷Java啦
🎇欢迎点赞收藏加关注哦!

类和对象2

  • 🍉匿名对象
  • 🍉关键字static
    • 🍌static修饰成员变量
    • 🍌static修饰成员方法
    • 🍌static成员变量初始化
  • 🍉代码块
    • 🍌普通代码块
    • 🍌构造代码块
    • 🍌静态块
  • 🍉继承
    • 🍌关键字extends
    • 🍌继承关系中的访问
    • 🍌关键字super
    • 🍌子类的构造方法
    • 🍌再谈初始化
    • 🍌继承关系中的访问权限
    • 🍌继承方式及关键字final
  • 🍉组合
  • 🍉写在最后

🍉匿名对象

特点:使用new来创建对象,但是不声明对象的引用变量
缺点:只能使用一次,不能重复使用

    System.out.println(new Student("sugar","male",21));

而数组也是一个对象,所以我们也可以采用匿名对象来打印数组:

    for (int i:array1) {System.out.print(i + " ");}System.out.println(" ");for(int i:new int[]{2,3,4,5,6}) {System.out.print(i + " ");}

在这里插入图片描述


🍉关键字static

之前在Student类中定义的成员变量,每个对象中都会包含一份(称之为实例变量)
而被static修饰的成员,称为静态成员,也可以称为类成员,它不属于某个具体的对象,而是所有对象共享的

(注意:static不可以修饰局部变量,因为局部变量不属于类)

🍌static修饰成员变量

特性:
●存储在方法区当中,不存储在某个对象的空间中。不属于某个具体的对象,是类的属性,所有对象共享的
●既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
●生命周期伴随类的一生(就是随类的加载而创建,随类的卸载而销毁)

🍌static修饰成员方法

静态成员方法也不是某个对象所特有的
可以通过对象调用,也可以通过类名.静态方法名(...)方式调用,更推荐使用后者

注意:
静态方法中不能调用非静态成员变量、非静态成员方法
因为调用非静态成员变量需要使用this来访问;调用非静态成员方法需要传一个this引用,而静态方法中不含this引用

🍌static成员变量初始化

静态成员变量的初始化分为两种:就地初始化静态代码块初始化
那什么是静态代码块呢?往下看~


🍉代码块

使用 {} 定义的一段代码称为代码块根据代码块定义的位置以及关键字,可以分为以下四种:
●普通代码块
●构造块
●静态块
●同步代码块(后续在多线程部分讲解)

🍌普通代码块

定义在方法中的代码块(这种用法较少见)

public class Main{public static void main(String[] args) {{ //直接使用{}定义,普通方法块int x = 10 ;System.out.println("x1 = " +x);}int x = 100 ;System.out.println("x2 = " +x);}
}

🍌构造代码块

构造代码块,又叫实例代码块。位于成员方法外、类里面,不用加修饰符,一般用于初始化成员变量,所以它只有在创建对象时才会执行

class Student {public String name;public String sex;public int age;//构造代码块{this.name = "zhangsan";this.sex = "male";this.age = 30;}
}public class Test {public static void main(String[] args) {Student student1 = new Student();System.out.println(student1);}
}

在这里插入图片描述

🍌静态块

使用static修饰的代码块称为静态代码块,也是位于成员方法外、类里面,一般用于初始化静态成员变量
比如对于学生类,有一个classroom的静态成员,那就使用静态块进行初始化

    public static String classroom;  //上课的教室static {classroom = "C-501";}

注意:
●不管生成多少个对象,每个静态块都只会执行一次
先执行静态块,然后执行构造块,再执行对应的构造方法
●如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行


🍉继承

面向对象思想中提出了继承的概念,用来提取不同类的共性,实现代码复用
继承允许在保持原有类特性的基础上进行扩展增加新功能,这样产生新的类,称为派生类

例如:狗和猫都是动物,那么我们就可以将共性的内容进行抽取,然后采用继承的思想来达到共用
在这里插入图片描述
在上图中,Dog类和Cat类都继承了Animal类,继承之后,子类可以复用父类中成员,子类在实现时只需关心自己新增加的成员即可

🍌关键字extends

Java中表示类之间的继承关系,需要用到关键字extends

//Animal.java
public class Animal {public String name;public int age;public void eat() {System.out.println(name+"在吃饭");}public void sleep() {System.out.println(name+"在睡觉");}
}//Cat.java
public class Cat extends Animal{void Catch() {System.out.println(name+"在抓老鼠");}
}//Dog.java
public class Dog extends Animal{void bark() {System.out.println(name+"在汪汪叫");}
}

子类会将父类中的成员变量成员方法继承到子类中
注意:被private修饰的成员变量,可以被子类继承,但是不能直接在子类中访问,要访问的话,需要在父类中写一个get方法间接访问

🍌继承关系中的访问

一、访问成员变量

①子类和父类不存在同名的成员变量
直接访问父类从父类继承下来的成员变量

②子类和父类存在同名的成员变量
优先访问子类的成员变量

不管是哪种情况,访问成员变量都遵循就近原则自己有就优先用自己的;如果没有再从父类中找


二、访问成员方法

①成员方法名字不同
成员方法没有同名时,在子类方法中或者通过子类对象访问方法时,优先访问自己的,自己没有时,再到父类中找,如果父类中也没有则报错

public class Base {public void methodA(){System.out.println("Base中的methodA()方法");}
}public class Derived extends Base{public void methodB(){System.out.println("Derived中的methodB()方法");}public void methodC(){methodB(); // 访问子类自己的methodB()methodA(); // 访问父类继承的methodA()}
}

②成员方法名字相同
通过子类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用的方法所传递的参数选择合适的方法访问,如果没有则报错

在了解这些访问顺序之后,有这样一个问题:如果子类中存在与父类相同的成员时,那该如何在子类中访问从父类中继承下来的同名的成员呢?
答案是:使用super关键字

🍌关键字super

使用super时需要注意它的使用场景:
●只能在非静态方法中使用
●在子类方法中,要访问父类的成员变量和方法的时候用

(当然,super还有其他用法,后面会讲)

public class Animal {public String name;public int age;public void method() {System.out.println("这是父类的method方法");}
}public class Dog extends Animal{public String name;public int age;public String color;@Overridepublic void method() {  //和父类的method方法构成重写System.out.println("这是子类的method方法");}public void method1() {method();super.method();  //用super访问父类的method方法}public static void main(String[] args) {Dog dog = new Dog();dog.method1();}
}

在这里插入图片描述

🍌子类的构造方法

构造子类对象时,需要先调用父类的构造方法,然后再执行子类的构造方法

子类构造方法中默认会调用父类无参的构造方法,即super()。你没有写的时候编译器会帮你自动添加上去
所以,如果你在父类中写了含参的构造方法,那你在子代构造方法里面就要显式调用super了,因为此时父类中已经没有编译器默认生成的无参构造函数

而且super一定要放在第一句,否则会报错

public class Animal {public String name;public int age;Animal(String name,int age) {this.name = name;this.age = age;}
}public class Dog extends Animal{public String color;Dog() {super("Zhangsan",15);  //显式调用superthis.color = "white";}
}

最后来总结一下super和this的异同之处:
同:
①只能在类的非静态方法中使用,用来访问非静态成员方法和字段;
②在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

异:
●this是当前对象的引用;super相当于是子类对象中从父类继承下来部分成员的引用

在非静态成员方法中,this用来访问本类的方法和属性;super用来访问父类继承下来的方法和属性
在构造方法中:this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造方法中出现
构造方法中一定会存在super(…)的调用,你没有写编译器也会添加;但是this(…)你不写就没有

🍌再谈初始化

再回顾一下上面所说的代码块的执行顺序
静态代码块->实例代码块->构造方法

结合继承关系,那么顺序就是:
父类静态代码块->子类静态代码块->父类实例代码块->父类构造方法->子类的实例代码块->子类构造方法
注意:第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

🍌继承关系中的访问权限

前面我们认识了四个访问限定符,那么父类中不同访问权限的成员,在子类中的可见性如何呢?
在这里插入图片描述
public和private就不用多说了,它们代表两个极端。父类中public修饰的成员,同个包和不同包中的子类都能访问;而private则都不行
要重点来说的是protected,展示一下不同包中的子类和非子类权限的区别:

//包1
public class Base {public int a;protected int b;
}//包2
//不同包中的子类
public class Derived extends Base{public void func() {super.a = 1;super.b = 666;  //正常访问}
}//包3
public class A1 {public static void main(String[] args) {Base base = new Base();base.a = 1;base.b = 1;  //报错,因为b在A1中不可见}
}

我们了解访问权限是为了能让类尽量做到“封装”,即隐藏内部实现细节,只暴露出必要的信息给类的调用者
因此我们在使用时应尽可能使用比较严格的访问权限。比如:如果一个方法能用 private,就尽量不要用 public

(当然,还有一种简单粗暴的做法:将所有的成员变量都设为 private,将所有的成员方法设为 public。但是这种方式属于滥用权限,不太推荐)
总而言之,写代码的时候要思考这个类提供的成员变量、方法到底给“谁”用的(是类内部自己用,还是类的调用者使用,还是子类使用)

🍌继承方式及关键字final

Java支持单继承多层继承不同类继承同一个类这三种继承方式,如图:


在实际项目中,我们不希望类之间的继承层次太复杂,一般我们不希望出现超过三层的继承关系,如果继承层次太多,就需要考虑对代码进行重构了

如果想从语法上限制继承,可以使用关键字final
final可以用来修饰变量、成员方法以及类

①修饰局部变量或成员变量,表示常量,不能再修改了

final int a = 10;
a = 20; // 编译出错

②修饰类,表示这个类不能被继承
修饰方法,表示该方法不能被重写


🍉组合

和继承类似,组合也是一种表达类之间关系的方式,它也可以实现代码复用。但是组合并没有涉及到特殊的语法(比如 extends 这样的关键字),它是将一个类的对象作为另外一个类的成员变量

关于二者的区别,通俗来说
●继承表示的对象之间是is-a的关系,比如:狗是一种动物(dog is an animal)
●而组合表示对象之间是has-a的关系,比如:汽车有多种零件,汽车和轮胎、发动机、方向盘、车载系统等的关系就是组合,因为汽车是由这些部件组成的

public class Engine {//...
}public class Tire {//...
}public class car {private Tire tire; // 可以复用轮胎中的属性和方法private Engine engine; // 可以复用发动机中的属性和方法
}// 奔驰是汽车
public class BenZ extends car{// 将汽车中包含的:轮胎、发送机、车载系统全部继承下来
}

●组合相较于继承,整体类与局部类彼此相对独立,不会破坏封装
●而对于继承,由于子类与父类之间紧密耦合,子类依赖于父类的实现,缺乏独立性,所以继承会破坏封装

简而言之就是:能用组合就尽量使用组合

继承要慎用,其使用场合仅限于你确信使用该技术有效的情况。一个判断方法是,问一问自己是否需要从新类向基类进行向上转型。如果是必须的,则继承是必要的。反之则应该好好考虑是否需要继承。——《Java编程思想》
只有当子类真正是超类的子类型时,才适合用继承。换句话说,对于两个类A和B,只有当两者之间确实存在is-a关系的时候,类B才应该继承类A。——《Effective Java》


🍉写在最后

以上就是本篇文章的全部内容,如果你觉得本文对你有所帮助的话,那不妨点个小小的赞哦!(比心)

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

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

相关文章

如何正确使用数据库的读写分离

本文已收录至我的个人网站:程序员波特,主要记录Java相关技术系列教程,共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源,让想要学习的你,不再迷茫。 背景 在应用系统发展的初期,我们并不知…

uniapp使用Android Studio离线打包

环境准备 Android Studio: 下载地址APP离线SDK下载: 下载地址; 目前我使用得是“Android-SDK3.8.7.81902_20230704”;需要与hbuider版本配套使用。Appkey: 参考我 以上三步准备好后,进行接下来的不住: 准备工程 导…

SpringCloud Config配置中心详解及环境搭建

前言 我们之前介绍并且搭建过eureka、zuul、hystrix组件。本节介绍的config是SpringCloud五大组件的最后一个,还有一个是Ribbon ----- 客服端负载均衡,之前我们有简单介绍过☞Eureka、Nacos注册中心及负载均衡原理,直接使用注解LoadBalanced…

统计学习 复习(知识点+习题)

复习资料:https://github.com/RuijieZhu94/StatisticalLearning_USTC 第一章 线性回归 1. From one to two 最小二乘 课后题 有偏/无偏估计 加权最小二乘 2. Regularization 线性回归(二维情况) 求解有约束优化问题 正则化最小加权二乘…

ByConity 社区回顾|ByConity 和开发者们一起展望未来,携手共进!

更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 新年伊始,我们想在这里感谢一群 ByConity 社区的小伙伴们。 正是因为有社区的开发者的支持,截止到 2023 年底,ByConity GitHub …

2023年全国职业院校技能大赛软件测试赛题—单元测试卷⑥

单元测试 一、任务要求 题目1:根据下列流程图编写程序实现相应分析处理并显示结果。返回结果“ax:”(x为2、3或4);其中变量x、y均须为整型。编写程序代码,使用JUnit框架编写测试类对编写的程序代码进行测试…

Java基础 - 黑马

我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 知…

使用MATLAB连接USRP

文章目录 前言一、本地环境二、前期准备1、MATLAB版本、labview版本、UHD 版本对应关系2、下载 GNU Radio Companion3、确定 USRP UHD 版本①、下载一个 USRP 硬件驱动程序②、确认 MATLAB 的 UHD 版本 三、下载 USRP 通信工具箱支持包四、使用 MATLAB 连接 USRP 前言 本文记录…

F-Droid:开源Android应用的宝库

F-Droid:开源Android应用的宝库 引言 F-Droid是一个开源应用程序存储库,旨在为安卓用户提供自由、隐私和安全的应用程序。它最初于2010年由Ciaran Gultnieks创建,因为他认为Google Play Store上的应用程序不够透明和安全。F-Droid的目标是为…

Web3与环保:区块链如何推动可持续发展

随着气候变化和环境问题日益严峻,社会对可持续发展的需求变得愈发迫切。在这个背景下,Web3技术和区块链崭露头角,成为推动可持续发展的关键力量。本文将深入探讨Web3技术如何与环保理念相结合,引领我们迈向更加可持续的未来。 1. …

每日一题——LeetCode1200.最小绝对差

方法一 个人方法 排序一次遍历: 最小差值一定是出现在大小相邻的两个元素之间,所以将数组从小到大排序 循环求两元素之间的差值,先假设当前差值为最小差值,先往res数组里面push数据,当碰到更小差值的时候&#xff0c…

VS 中调用调试DLL库的方法

前提条件: 1、当前代码是最新的,并且编译成dll的库有程序使用。 2、打开运行dll库的程序。 配置步骤: 1、使用VS打开要调试的dll库项目。 2、点击调试菜单展开调试菜单。 3、点击附加到进程,弹出配置框。 4、在配置框中选…

学习笔记-数据库概念介绍

一.数据库概述 1.数据库: 存储数据的仓库,本质是一个文件系统. 用户可以对数据库中的数据进行 增加,修改,删除以及查询操作 2.特点 可以结构化存储大量的数据可以有效的保持数据的一致性,完整性读写效率高 3.常用数据库 二.数据库分类及其常用 关系型数据库 指的是二维表格…

【51单片机系列】51单片机的中断系统使用总结一

本文是在学习51单片机的中断系统的简单性总结,着重于51单片机的中断系统的工作原理及如何使用。 文章目录 一、中断原理简单介绍二、 外部中断相关介绍2.1 与外部中断相关的寄存器2.2、外部中断0使用示例2.3、外部中断1使用示例 三、定时器中断相关介绍3.1、51单片机…

基于Ubuntu22.04部署生产级K8S集群v1.27(规划和核心组件部署篇)

本文档主要根据k8s官网文档和其插件的官网文档,参考部分他人优秀经验,在实际操作中逐渐完成,比较详尽,适合在境内学习者和实践者参考。 实操环境基于VMware Workstation 17 pro,采用ubuntu22.04操作系统(有…

链接全域直播产业经济,天府锋巢直播产业基地10层正式起航

100㎡-400㎡多种类型的办公户型可选 精装全包 拎包入驻 【天府锋巢直播基地】 由德商产投与无锋科技联袂打造 坐落于天府新区核心区域科学城板块 包含电商直播、娱乐直播、跨境直播 多种直播业态的全域直播基地 基地【10层】于12月初全面竣工 招|商 |火&…

中小企业如何做好信息化规划?

中小企业需不需要做信息化规划?什么时候做信息化规划比较好? 企业的信息化规划,一定是越早越好,越快越好。 因为信息化是一个过程,不是一个结果,它不是一天完成的事情,而是贯穿着企业经营管理…

鸿蒙应用开发学习:让page页面强制横屏

一、学习做了个适合横屏的页面但进入页面后是竖屏显示的 前几天在B站上跟着 黑马程序员的 HarmonyOS4.0开发应用教学视频学习了显式动画(animateTo)和属性动画(animation)功能,并参照教学视频的内容做了个小鱼动画。…

瑞_Java开发手册_(五)MySQL数据库

文章目录 (一) 建表规约(二) 索引规约(三) SQL 语句(四) ORM 映射附:雪花算法(Java) 🙊前言:本文章为瑞_系列专栏之《Java开发手册》的MySQL数据库篇,主要介绍建表规约、索引规约、SQL语句、ORM映射。由于博…

力扣hot100 路径总和Ⅲ dfs 前缀和 一题双解 超全注释

Problem: 437. 路径总和 III 思路 树的遍历 DFS 一个朴素的做法是搜索以每个节点为根的(往下的)所有路径,并对路径总和为 targetSumtargetSumtargetSum 的路径进行累加统计。 使用 dfs1 来搜索所有节点,复杂度为 O(n)O(n)O(n)&am…