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

类和对象续

目录

自定义包

包的访问权限控制

常见的包

Static成员

静态成员变量

静态成员方法

代码块 

构造块

静态块

重写 

继承

继承是啥?

父类成员访问

子类中访问父类成员变量

两者不同名

两者同名

子类中访问父类对的成员方法

super

子类构造方法

this和super

 代码块再解读

protected关键字

继承方式

 多态

向上转型:把子类所引用的对象给到父类

再说重写 

向下转型

多态的好处


自定义包

选中src右键选择new-->package,创建名字

创建好名字后在下方新建一个testwww

建完的界面就是这样滴

包的访问权限控制

在自定义包下创建新程序TestOne和一个新的包demo,在demo下再创建一个新程序TestTwo

//TestOne
package com.bitejiuyeke.www;public class TestOne {String name = "zhangsan";public static void main(String[] args) {}
}

因为封装在TestTwo中无法引用TestOne中的变量。

常见的包

1. java.lang: 系统常用基础类 (String Object), 此包从 JDK1.1 后自动导入。
2. java.lang.reflflect:java 反射编程包 ;
3. java.net: 进行网络编程开发包。
4. java.sql: 进行数据库开发的支持包。
5. java.util: java 提供的工具程序包。 ( 集合类等 ) 非常重要
6. java.io:I/O 编程开发包。

Static成员

静态成员变量

 假设学生都在一个教室上课

我们就把classroom拿出来当成静态类

public static String classroom;

特性:

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

静态成员方法

public class Student{// ...private static String classRoom = "Bit306";// ...public static String getClassRoom(){return classRoom;}
}
public class TestStudent {public static void main(String[] args) {System.out.println(Student.getClassRoom());}
}

 特性

1. 不属于某个具体的对象,是类方法
2. 可以通过对象调用,也可以通过类名 . 静态方法名 (...) 方式调用,更推荐使用后者
3. 不能在静态方法中访问任何非静态成员变量

初始化

1.就地初始化

直接赋值

2.代码块初始化

代码块 

构造块

静态块

结论:

静态代码块先执行

然后执行构造代码块

在实行对应的构造方法

静态的只执行1次  

同步代码块

这些静态代码块可以合并成一个代码块


重写 

    public static void main(String[] args) {Student student = new Student("张三",10);System.out.println(student);}

打印结果是

为什么会打印粗这样的结果呢?

我们control点进去println底层

valueOf底层

toString底层

我们完全可以再自己代码中重新写一个toString方法,这样系统不会调用底层的代码,而会先考虑你写的新方法

点击鼠标右键选择generate,点进去toString,系统帮你生成一段新的打印代码,利用这段代码就可以正常打印了

    @Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';//return "lalala"//这样就可以打印lalala}

这种方法叫做重写


    //方法1    public static int add(int a,int b) {return a+b;}//方法2public static int add(int a,int b,int c) {return a+b+c;}//方法3public static int add(int[] array) {int ret = 0;for (int x: array) {ret += x;}return ret;}public static void main(String[] args) {int[] array = {1, 2, 3, 4, 5};System.out.println(add(array));System.out.println(add(new int[]{1, 3, 4, 5, 6}));//匿名对象}

方法3还有一个更🐂的重写方法

    /*** ...可变参数* @param array* @return*/public static int add(int... array){int ret = 0;for (int x: array) {ret += x;}return ret;}

继承

继承是啥?

这两个类都有相同的eat方法

每个动物都有这几个共同的特点,把这些类的共性进行抽取,放到特定的类中,从而达到代码的复用效果。这种类就叫继承

抽取新建共性类Animal

class Animal{//抽取出来的类public String name;public int age;public void eat(){System.out.println(this.name + "正在吃饭");}
}

 

这里的Dog跟Animal是is-a的关系,Dog称为子类或者派生类,Animal称为父类或者基类或者超类

extends是拓展的意思,也就是继承


在Animal类中,访问修饰限定符只能决定访问权限,不能决定能不能被继承

所以在后面的类中,虽然name不能被访问,但是是可以继承的,提供一个get方法就能访问


父类成员访问

子类中访问父类成员变量

两者不同名
class Base{public int a;public int b;
}
class Derived extends Base{public int c;public void method(){a = 1;b = 2;c = 3;}
}
public class Test2{public static void main(String[] args) {Derived derived = new Derived();}
}

 这样的访问是不受限制的


两者同名
class Base{public int a = 9;public int b = 99;
}
class Derived extends Base{public int a = 88;public void method(){System.out.println("a: " + a);System.out.println("b: " + b);}
}

打印结果: 

当父类和子类的成员变量同名时,在子类当中使用时,优先打印子类的成员变量

总结:成员变量访问遵循就近原则,自己有优先自己的,没有再从父类中找


子类中访问父类对的成员方法

跟上面的成员变量访问差不多

通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到
则访问,否则编译报错。
通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同 ( 重载 ) ,根据调用
方法适传递的参数选择合适的方法访问,如果没有则报错;

如果子类中存在和父类相同的成员时,怎么再子类中访问父类相同名称的成员呢?

super

super在子类方法中访问父类的成员变量和方法


子类构造方法

回到刚才的Animal类中,构造Animal类的构造方法

Dog报错了,因为子类没有初始化父类成员,子类在构造完之前,一定要帮助父类进行初始化

圆圆和10就是对name和age的初始化

或者这样写(generate-->constructor)

    public Dog(String name, int age){super(name, age);}

super()调用父类的构造方法,帮助初始化子类从父类继承过来的成员,并不会生成父类对象

this和super

相同点
1. 都是 Java 中的关键字
2. 只能在类的非静态(main不行)方法中使用,用来访问非静态成员方法和字段
3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在
不同点
1. this 是当前对象的引用,当前对象即调用实例方法的对象, super相当于是子类对象中从父类继承下来部分成员的引用
2. 在非静态成员方法中, this 用来访问本类的方法和属性, super 用来访问父类继承下来的方法和属性
3. 在构造方法中: this(...) 用于调用本类构造方法, super(...) 用于调用父类构造方法,两种调用不能同时在构造方法中出现
4. 构造方法中一定会存在 super(...) 的调用,用户没有写编译器也会增加,但是 this(...) 用户不写则没有

 代码块再解读

class Animal{//抽取出来的类public String name;public int age;public void eat(){System.out.println(this.name + "正在吃饭");}static {System.out.println("Animal::static{静态}");}{System.out.println("Animal::{实例}");}public Animal(String name, int age) {this.name = name;this.age = age;System.out.println("Animal(String name, int age)");}
}
//拓展
class Dog extends Animal{//狗继承了Animalstatic{System.out.println("Dog::static{静态}");}{System.out.println("Dog::{实例}");}public Dog(String name, int age){super(name, age);System.out.println("Dog(String name, int age)");}public void bark() {System.out.println(this.name+ " 正在旺旺叫!");}
}
class Test{public static void main(String[] args) {Dog dog = new Dog("圆圆",10);}
}

 打印结果是什么呢?

两个静态优先执行,父类再执行,子类最后执行

再多两行代码

        System.out.println("================");Dog dog2 = new Dog("圆圆",10);

静态的就不执行了


protected关键字

package demo;public class Test3 {protected int a = 19999;
}

为什么不能打印a,就算调用super也不行呢?

因为demo2里面的Test既不是Test3的子类,又与Test3处于不同包

看回之前的那张表,这张表在我一篇博客提过

JAVA类和对象_cx努力编程中的博客-CSDN博客

此时protected正好满足第四类的限制

这个表格的前提继承的父类是由public修饰的

注意:这里的public不能替换成private或者protected


继承方式

1.现在有一需求:当集成到某个层次上之后我们不再继承了

final是密封类,表示当前不能继承了。

final的另一个用法。下面的a只能初始化一次,成为了常量,恒等于199,再次初始化会报错。

        final int a = 199;a = 20;//errSystem.out.println(a);

final代表不可变 e.g String

2.组合(has-a/a part of关系)

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

 多态

同一个人对待不同人表现出不一样的形态,这可以理解为最基本的多态

条件:

1.继承关系上-->向上转型

2.子类和父类有同名的覆盖/重写方法

3.通过父类对象的引用去调用这个重写的方法


向上转型:把子类所引用的对象给到父类

常见的可以发生线上转型的三个时机 

//1.直接赋值/*Dog dog = new Dog("圆圆",10);animal这个引用指向dog这个引用所指向的对象;Animal animal = dog;*/Animal animal = new Dog("圆圆",10);
//2.方法的参数,传参的时候进行向上转型public static void func1(Animal animal){}public static void main(String[] args) {Dog dog = new Dog("圆圆",10);func1(dog);}
//3.返回值向上转型public static Animal func2(){Dog dog = new Dog("圆圆",10);return dog;}

再说重写 

当我们在Dog类中加入eat()方法

    public void eat(){System.out.println(this.name + "正在吃狗粮!");}
//Animal  public void eat(){System.out.println(this.name + "正在吃饭");}
//Testpublic static void main(String[] args) {Animal animal = new Dog("圆圆",10);animal.eat();}

打印结果是

这两个eat方法满足方法返回值一样,方法名一样,方法的参数列表一样 

继承关系上,这两个方法关系是重写

但是在调用的时候忽然变成了调用子类的eat,这个过程叫做动态绑定

子类如果有eat方法那就调用子类的,子类没有就调用父类的

程序在编译的时候,确实调用的是Animal的eat

程序在运行时,调用了Dog的eat方法,是在这个时候才绑定方法(区分静态绑定)


静态绑定是什么呢?

像这种在编译的时候已经确定了调用谁,就是静态绑定


我们在写重写时,一般要在上面加一个注释,这个注释可以帮助你避免一些错误

 实现重写:

1.最基本的返回值参数列表,方法名必须是一样的

2.被重写的方法的访问修饰限定符在子类中要大于等于父类的

访问修饰限定符大小关系:private>default>protected>public

3.被private,static,final修饰的方法和构造方法是不能被重写的

4.被重写的方法返回值类型可以不同,但必须有父子关系,比如:

这种叫做协变类型 

重写快捷方法,鼠标右键选generate,选择要重写的方法


    public static void eatFun(Animal animal){animal.eat();}public static void main(String[] args) {Dog dog = new Dog("圆圆", 19);eatFun(dog);Cat cat = new Cat("咪咪", 1);eatFun(cat);}
//圆圆正在吃狗粮!
//咪咪 正在吃猫粮!

当父类引用的子类对象不一样的时候,调用这个重写的方法,所表现出来的行为是不一样的!我们把这种思想叫做多态

向下转型

我们知道dog和cat都属于animal,但是反过来,animal就一定是dog吗,这里拿一个大类去调用一个小类的方法明显不可能

我们需要强制转换类型,这也叫做向下转型,但是这种转型非常不安全

当我们使用cat类的时候就发现类型转换异常,就算强行转换也无济于事

那我如何避免用错类来向下转型呢?我们可以用instanceof

        if (animal instanceof Cat) {Cat cat = (Cat) animal;cat.miaomiao();}else{System.out.println("好吧!");}

多态的好处

class Rect extends Shape{@Overridepublic void draw(){System.out.println("矩形");}
}class  Triangle extends Shape{@Overridepublic void draw() {System.out.println("🔺!");}
}class Cycle extends Shape{@Overridepublic void draw() {System.out.println("圆形!");}
}public class Test {public static void main(String[] args) {Cycle cycle = new Cycle();Rect rect = new Rect();Triangle triangle = new Triangle();String[] strings = {"cycle","rect","cycle","rect","triangle"};for(String x :strings){if(x.equals("cycle")){cycle.draw();}else if (x.equals("rect")){rect.draw();}else if (x.equals("triangle")){triangle.draw();}}}
}

如果有大量的条件和循环语句,这种代码拥有圈复杂度,我们可以用多态来降低这种复杂度

    public static void drawMap(Shape shape){shape.draw();}public static void main(String[] args) {Shape[] shapes = {new Cycle(), new Rect(), new Cycle(), new Rect(), new Triangle()};for(Shape shape: shapes){shape.draw();}}

这段代码的扩展能力非常强,在上方添加一个类下面就能给你画出来

相关文章:

类和对象续

目录 包 自定义包 包的访问权限控制 常见的包 Static成员 静态成员变量 静态成员方法 代码块 构造块 静态块 重写 继承 继承是啥? 父类成员访问 子类中访问父类成员变量 两者不同名 两者同名 子类中访问父类对的成员方法 super 子类构造方法 …...

SpringCloud:Feign实现微服务之间相互请求

文章目录 🎉欢迎来到Java学习路线专栏~SpringCloud:Feign实现微服务之间相互请求 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页:IT陈寒的博客🎈该系列文章专栏:Java学习路线📜其他专栏&#xf…...

LeetCode 1359. Count All Valid Pickup and Delivery Options【动态规划,组合数学】1722

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...

[杂谈]-从硬件角度理解二进制数

从硬件角度理解二进制数 文章目录 从硬件角度理解二进制数1、概述2、模拟电路3、数字电路4、逻辑电平5、TTL 器件的电压水平6、总结 1、概述 二进制数以 2 为基数系统表示,该系统只有两 (2) 个不同的数值,即 0 和 1。就像最常见的那样,十进制…...

Fast-DDS 服务发现简要概述

阅读本文章需要对DDS基础概念有一些了解,一些内容来自Fast-DDS官方文档,一些是工作中踩过的坑。 1. 服务发现阶段 满足OMG标准的DDS服务发现分为两部分,分别是: PDP(Participant Discovery Protocol 参与者发现协议):参与者确认…...

基于spingboot的websocket订阅、广播、多人聊天室示例

概述 基于spingboot的websocket多人聊天系统。包括订阅,广播、点对点单人聊天,多人聊天室功能。 详细 一、运行效果 简单示例 广播 单人聊天 多人聊天室 二、相关代码 websocket配置 package com.iamgpj.demowebsocket.config;import com.iamgpj.d…...

Linux mac Windows三系统 局域网文件共享方法

主要工具: Samba是一个开源的软件套件,允许Linux系统与Windows系统之间共享文件和打印机。 一、首先是Linux共享的设置 ①安装 sudo apt-get install samba ②创建共享文件夹 sudo mkdir /home/share ③配置用户 sudo smbpasswd -a kequan ④修改…...

Java——比较器

引入的背景 我们知道基本数据类型的数据(除boolean类型外)需要比较大小的话,直接使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。那么,如何解决这个问题呢? 在Java中经常会涉…...

【数据结构】初识泛型

文章目录 一般的类和方法,只能使用具体的类型: 要么是基本类型,要么是自定义的类。这种限制对代码的束缚就会很大。所以我们引入了泛型。泛型,泛顾名思义就是广泛的意思。就是适用于许多许多类型。从代码上讲,就是对类型实现了参数…...

代码随想录--哈希--有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 示例 1: 输入: s "anagram", t "nagaram" 输出: true 示例 2: 输入: s "rat", t "car" 输出: false 说明: 你可以假设字符串只包含小写字母。…...

MySQL——数据的增删改

2023.9.12 本章开始学习DML (数据操纵语言) 语言。相关学习笔记如下: #DML语言 /* 数据操作语言: 插入:insert 修改:update 删除:delete */#一、插入语句 #方式一:经典的插入 /* 语法: insert …...

云服务器与http服务器

如何与http服务器建立连接(客户端)? http请求设计格式: 例子: 发送http请求 http数据响应格式: 接收http服务器返回的数据需要进一步进行字符串处理操作,提取有用的数据。...

golang教程 beego框架笔记一

安装beego 安装bee工具 beego文档 # windos 推荐使用 go install github.com/beego/bee/v2master go get -u github.com/beego/bee/v2masterwindows使用安装bee工具时碰到的问题; 环境配置都没有问题,但是执行官网的命令:go get -u github…...

【深度学习】Mini-Batch梯度下降法

Mini-Batch梯度下降法 在开始Mini-Batch算法开始之前,请确保你已经掌握梯度下降的最优化算法。 在训练神经网络时,使用向量化是加速训练速度的一个重要手段,它可以避免使用显式的for循环,并且调用经过大量优化的矩阵计算函数库。…...

AI项目六:WEB端部署YOLOv5

若该文为原创文章,转载请注明原文出处。 一、介绍 最近接触网页大屏,所以就想把YOLOV5部署到WEB端,通过了解,知道了两个方法: 1、基于Flask部署YOLOv5目标检测模型。 2、基于Streamlit部署YOLOv5目标检测。 代码在…...

敲代码常用快捷键

1、代码拖动 PyCharm:按住 shiftalt鼠标选中某一区域来拖动,即可实现拖动这一区域至指定区域。Visual Studio Code (VSCode): - Windows/Linux:Alt 鼠标左键拖动 - MacOS:Option 鼠标左键拖动 IntelliJ IDEA: - Win…...

MyBatis: 分页插件PageHelper直接传递分页参数的用法

一、加分页插件依赖 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.2.13</version></dependency>二、配置分页插件&#xff0c;并配置相关属性&a…...

Python基于Flask的高校舆情分析,舆情监控可视化系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 运行效果图 基于Python的微博大数据舆情分析&#xff0c;舆论情感分析可视化系统 系统介绍 微博舆情分析系…...

Python第一次作业练习

题目分析&#xff1a; """ 参考学校的相关规定。 对于四分制&#xff0c;百分制中的90分及以上可视为绩点中的4分&#xff0c;80 分及以上为3分&#xff0c;70 分以上为2分&#xff0c;60 分以上为1分; 五分制中的5分为四分制中的4分&#xff0c;4分为3分&#…...

InstallShield打包升级时不覆盖原有文件的解决方案

一个.NET Framework的Devexpress UI Windows Form项目&#xff0c;用的InstallShield&#xff0c;前些个版本都好好的&#xff0c;最近几个版本突然就没法更新了&#xff0c;每次更新的时候都覆盖不了原文件&#xff0c;而且这样更新后第一次打开程序&#xff08;虽然是老程序&…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...