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

Java—类与对象(一)

Java是完全面向对象的开发技术,每个对象中包含对用户公开的特定功能部分和隐藏的实现部分。

一、相关概念

1.1 类

类是构造对象的模板或蓝图,由类构造对象的过程称为创建类的实例。

1.1.1 类之间的关系

1.1.1.1 依赖

依赖,即“uses-a”关系,如果一个类的方法操纵另一个类的对象,就说一个类依赖于另一个类,应该尽可能减少相互依赖的类(让类之间的耦合度最小),这样一个类的改变导致其他类产生bug的概率会尽可能减少。

1.1.1.2 聚合

聚合,即“has-a”关系,即一个类的对象包含着另一个类的对象。

1.1.1.3 继承

继承,即“is-a”关系,如果类A继承类B,那么类A不仅能使用其本身的方法,还能够调用从类B继承来的方法。但类B无法使用类A的方法。

补充

  • 一个文件中可以包含多个类 
  • 一个文件中有且只能有一个被public修饰且类名与文件名相同的类;

1.2 封装

封装(也称数据隐藏)将数据和行为组合在一个包中,隐藏其具体的实现方式,对外只提供接口、调用方式。

实现封装的关键在于不能让类的方法直接访问其他类的实例域(数据)。

需要获取或设置实例域的值时,需要提供:

  • 一个私有的数据域
  • 一个共有的域访问器方法
  • 一个共有的域更改器方法

1.3 对象

对象是类的实例,对象中的数据称为实例域,操纵数据的过程称为方法。每个特定的类实例(对象)都有一组特定的实例域值。这些值的集合就是这个对象的状态。

同一个类的对象由于支持相同的行为而具有相似性,但每个对象都有唯一的身份标识,例如即使两个相同商品的订单也是不同的。

1.3.1 对象的三大特性

  • 对象的行为—可以对对象施加的操作或方法,通过其可调用的方法定义。
  • 对象的方法—向对象施加方法后,对象的响应。
  • 对象标识—分辨具有相同行为与状态的不同对象。

二、预定义类

在Java中有些类没有面向对象特征,如Math类,可以通过Math.方法名(参数)对其进行调用。

2.1 构造器

想要使用对象,必须先构造对象并指定其初始状态,在Java中创建对象必须通过构造器。

  • 构造器是一种特殊的方法,用来构造并初始化对象,总伴随着new一起用。
  • 构造器的方法名与类名一致。
  • 类中默认存在构造器,默认构造器为无参构造器。
  • 可以对构造器进行重写,重写的构造器会覆盖默认构造器。
  • 每个类可以有一个及以上的构造器,构造器的参数可以有0个、1个或多个参数。
  • 在类中可以创建多个方法签名(方法名+参数列表)不同的构造器。

2.2 LocalDate类

public class LocalDate {public static void main(String[] args) {java.time.LocalDate a1 = java.time.LocalDate.now();java.time.LocalDate a2 = java.time.LocalDate.of(2015,06,15);System.out.println(a1);	System.out.println(a2);System.out.println(a2.getYear());System.out.println(a2.getMonthValue());System.out.println(a2.getDayOfMonth());}
}

运行结果

2025-05-14
2015-06-15
2015
6
15

(1)LocalDate.now()  会构造一个新对象,返回当前日期

(2)LocalDate.of(2015,06,15)  会构造一个指定日期的新对象

(3)LocalDate对象.getYear()  获取该对象的年份

(4)LocalDate对象.getMonthValue()  获取该对象的年份

(5)LocalDate对象.getDayOfMonth()  获取该对象的日期

2.3 更改器与访问器方法

更改器方法:调用方法后,对象状态会改变。

访问器方法:只访问对象而不修改对象的方法。

示例:日历

package com.qcby.第四章;import java.time.DayOfWeek;
import java.time.LocalDate;public class 日历 {public static void main(String[] args) {LocalDate date = LocalDate.now();int month = date.getMonthValue();int today = date.getDayOfMonth();date = date.minusDays(today-1);DayOfWeek weekday = date.getDayOfWeek();int value = weekday.getValue();System.out.println("Mon Tue Wed Thu Fri Sat Sun");for(int i = 1;i<value;i++) {System.out.print("    ");while(date.getMonthValue() == month) {System.out.printf("%3d",date.getDayOfMonth());if(date.getDayOfMonth() == today)System.out.print("*");elseSystem.out.print(" ");date = date.plusDays(1);if(date.getDayOfWeek().getValue()==1) System.out.println();}if(date.getDayOfWeek().getValue()!=1) System.out.println();}}
}

运行结果

Mon Tue Wed Thu Fri Sat Sun1   2   3   4 5   6   7   8   9  10  11 12  13  14* 15  16  17  18 19  20  21  22  23  24  25 26  27  28  29  30  31 

三、自定义类

3.1 显式参数与隐式参数

隐式参数是指在方法中使用但没有在方法参数中声明的变量。通常,这些变量是在类中声明的实例域。隐式参数的一个典型例子是使用this关键字引用当前对象的实例域。

显式参数会明显的列在方法声明中,如下面代码中的int num

public class Test{public int a = 10; //隐式参数//this 关键字指向当前对象实例,但静态方法不依赖于实例,所以在静态方法中不能使用this关键字public void b(int num) {  //num 显式参数  void声明没有返回数据,若有返回需要写明类型this.a+=num;System.out.println(a);}public static void main(String[] args) {new LocalDate().b(5);}
}

运行结果

15

3.2 this关键字

this关键字是一个指向当前对象实例的引用。它的核心作用是帮助在对象的方法或构造器中明确访问当前实例的成员。

3.2.1 this关键字用途

3.2.1.1 解决成员变量与局部变量同名冲突
public class test {private String name; // 成员变量public void setName(String name) { // 参数名与成员变量同名this.name = name; // 用 this 明确指向成员变量System.out.println(name);}public static void main(String[] args) {new test().setName("nameA");}
}

运行结果

nameA
  • 当方法参数与成员变量同名时,this用于区分成员变量和局部变量。
3.2.1.2 在构造器中调用其他构造器
public class test {private String name; public static void main(String[] args) {System.out.println(new test());}public test(String name) {this.name = name;}public test() {this("nameA"); //必须是构造器的第一条语句}@Overridepublic String toString() {return "test [name=" + name + "]";}}

运行结果

test [name=nameA]
  • 规则:不使用方法名,直接用this(...)调用,且必须是构造器的第一条语句

  • 用途:减少重复代码,实现构造器的链式调用。

3.2.1.3 返回当前对象实例
public class test {private int count; public test Count() {count++;++count;return this;   //返回当前对象,实现链式调用}public static void main(String[] args) {System.out.println(new test().Count());}@Overridepublic String toString() {return "test [count=" + count + "]";}	
}

运行结果

test [count=2]
3.2.1.4 内部类访问外部类实例
public class test {private int count = 5; class inner{public void a() {System.out.println(test.this.count); //访问外部类成员}}@Overridepublic String toString() {return "test [count=" + count + "]";}	
}

测试

public class test1 {public static void main(String[] args) {test a = new test();System.out.println(a);}
}

运行结果

test [count=5]
  • 注意:内部类中直接使用this指向的是内部类实例,需通过外部类名.this访问外部类成员。

 3.2.2 this关键词的限制

(1)不能在静态方法中使用

        静态方法属于类而非实例,this无指向目标。

(2)不能在静态代码块中使用

        静态代码块在类加载时执行,此时没有对象实例。

(3)在构造器中调用必须位于第一行

        通过this()调用其他构造器时,必须作为构造器的第一条语句

3.2.3 与super()区别

3.2.3.1 super()的用途 
3.2.3.1.1 显式调用父类指定构造器

父类

public class test {public int count; public test(int count) {super();this.count = count;}	
}

子类

public class test1 extends test{String a;public test1(int count, String a) {super(count);this.a = a;}public static void main(String[] args) {System.out.println(new test1(5,"A"));}@Overridepublic String toString() {return "test1 [a=" + a + " count="+count+"]";}}

运行结果

test1 [a=A count=5]

若父类没有无参构造器,子类构造器必须显式调用super(参数)

3.2.3.1.2 访问被覆盖的父类成员

父类

public class test {void print() {System.out.println("Parent");}	
}

子类

public class test1 extends test{@Overridevoid print() {super.print(); // 调用父类被覆盖的方法System.out.println("Child");}public static void main(String[] args) {new test1().print();}	
}

运行结果

Parent
Child
3.2.3.1.3 解决子类与父类字段名冲突

 父类

public class test {int count = 100;	
}

子类

public class test1 extends test{int count = 200;void show() {System.out.println(super.count); // 访问父类的 count (100)System.out.println(this.count);  // 访问本类的 count (200)}	public static void main(String[] args) {new test1().show();}
}

运行结果

100
200
3.2.3.2 super()限制
3.2.3.2.1 super()和this()不能共存

如图,若super()和this()同时存在,在下面的那个会报错。

3.2.3.2.2 默认的super()陷阱
class Parent {Parent(int num) { } //父类没有无参构造器
}class Child extends Parent {Child() { //隐式super()会尝试调用Parent(),但父类没有无参构造器}
}

修改

Child() {super(100); // 强制指定父类构造器
}

http://www.xdnf.cn/news/6079.html

相关文章:

  • LLM(大语言模型)部署加速方法——PagedAttention
  • c# 倒序方法
  • 【Java】 volatile 和 synchronized 的比较及使用场景
  • 【RabbitMQ】路由模式和通配符模式的具体实现
  • 嵌入式培训之数据结构学习(三)gdb调试
  • dify 连接不上ollama An error occurred during credentials validation:
  • gitlab提交测试分支的命令和流程
  • HCIP(BFD)
  • Linux——CMake的快速入门上手和保姆级使用介绍、一键执行shell脚本
  • 硬盘序列号(SN码)4种常用查询方法分享
  • Java基础之静态代理和动态代理
  • ValueError: 4 columns passed, passed data had 51141 columns解决
  • 【消息队列】RabbitMQ基本认识
  • Git仓库迁移
  • 深度解析 Sora:从技术原理到多场景实战的 AI 视频生成指南【附学习资料包下载】
  • 模糊数学方法之模糊贴近度
  • 现代 Web 自动化测试框架对比:Playwright 与 Selenium 的深度剖析
  • AI智能分析网关V4周界入侵检测算法精准监测与智能分析,筑牢周界安全防线
  • flutter 视频通话flutter_webrtc
  • @Controller 与 @RestController-笔记
  • 架构设计不合理,如何优化系统结构
  • 设计并实现高并发系统,应用无锁编程与CAS机制
  • Android usb网络共享详解
  • Linux笔记---信号(中)
  • 计算机视觉----基础概念、卷积
  • 基于javaweb的SpringBoot自习室预约系统设计与实现(源码+文档+部署讲解)
  • VUE3 -综合实践(Mock+Axios+ElementPlus)
  • 基于Matlab的非线性Newmark法用于计算结构动力响应
  • 如何查看打开的 git bash 窗口是否是管理员权限打开
  • Oracle 中的虚拟列Virtual Columns和PostgreSQL Generated Columns生成列