java--面向对象基础
类的定义
面向过程 :是一种以过程为中心的编程思想,实现功能的每一步,都是自己实现的
面向对象 :是一种以对象为中心的编程思想,通过指挥对象实现具体的功能
-
类的理解
- 类是对现实生活中一类具有共同属性和行为的事物的抽象
- 类是对象的数据类型,类是具有相同属性和行为的一组对象的集合
- 简单理解:类就是对现实事物的一种描述
-
类的组成
- 属性:指事物的特征,例如:手机事物(品牌,价格,尺寸)
- 行为:指事物能执行的操作,例如:手机事物(打电话,发短信)
-
类和对象的关系
- 类:类是对现实生活中一类具有共同属性和行为的事物的抽象
- 对象:是能够看得到摸的着的真实存在的实体
- 简单理解:类是对事物的一种描述,对象则为具体存在的事物
类的定义
public class Student { //定义一个公共类,都可以访问调用该类
// 属性 : 姓名, 年龄
// 成员变量: 跟之前定义变量的格式一样, 只不过位置发生了改变, 类中方法外
String name;
int age;
// 行为 : 学习
// 成员方法: 跟之前定义方法的格式一样, 只不过去掉了static关键字.
public void study(){
System.out.println("学习");
}
}
对于一个类来说,有三种成员:属性 field、方法 method、构造器 constructor。
属性(field 成员变量)
属性用于定义该类或该类对象包含的数据或者说静态特征。属性作用范围是整个类体。
在定义成员变量时可以对其初始化,如果不对其初始化,Java 使用默认的值对其初始化。
数据类型 | 默认值 |
整型 | 0 |
浮点型 | 0.0 |
字符型 | '\u0000' |
布尔型 | false |
所有引用类型 | null |
属性定义格式:
[修饰符] 属性类型 属性名 = [默认值] ;
方法
方法用于定义该类或该类实例的行为特征和功能实现。方法是类和对象行为特征的抽象。面向对象中,整个程序的基本单位是类,方法是从属于类和对象的。
[修饰符] 方法返回值类型 方法名(形参列表) {
// n 条语句
}
构造方法(构造器 constructor)
构造器用于对象的初始化
声明格式:
[修饰符] 类名(形参列表){
//n 条语句
}
构造器 4 个要点:
- 构造器通过 new 关键字调用!!
- 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用 return 返回某个值。
- 如果我们没有定义构造器,则编译器会自动定义一个无参的构造方法。如果已定义则编译器不会自动添加!
- 构造器的方法名必须和类名一致
/*
定义一个“点”(Point)类用来表示二维空间中的点(有两个坐标)。要求如下:
可以生成具有特定坐标的点对象。
提供可以计算该“点”距另外一点距离的方法。
*/
class Point { // 定义一个类
double x, y; // 属性
public Point(double _x, double _y) { // 有参构造方法
x = _x;
y = _y;
}
public double getDistance(Point p) { //一个成员方法,返回类型为double
return Math.sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y));
}
public static void main(String[] args) { // 入口
Point p1 = new Point(3.0, 4.0);
Point origin = new Point(0.0, 0.0);
System.out.println(p1.getDistance(origin));
}
}
构造方法的重载
构造方法重载(创建不同用户对象)
构造方法重载(创建不同用户对象)
public class User {
int id; // id
String name; // 账户名
String pwd; // 密码
public User() {
}
public User(int id, String name) {
this.id = id;
this.name = name;
}
public User(int id, String name, String pwd) { // 构造方法重载
this.id = id;
this.name = name;
this.pwd = pwd;
}
public static void main(String[] args) {
User u1 = new User();
User u2 = new User(101, "小七"); // 使用的是有两个参数的构造方法
User u3 = new User(100, "张三", "123456"); // 使用的是三个参数的构造方法
}
}
回顾方法重载:
- 指同一个类中定义的多个方法之间的关系,满足下列条件的多个方法相互构成重载
- 多个方法在同一个类中
- 多个方法具有相同的方法名
- 多个方法的参数不相同,类型不同或者数量不同
特点:
- 类型不同或者数量不同重载仅对应方法的定义,与方法的调用无关,调用方式参照标准格式
- 重载仅针对同一个类中方法的名称与参数进行识别,与返回值无关,换句话说不能通过返回值来判定两个方法是否相互构成重载
对象的创建和使用
创建对象的格式:
类名 对象名 = new 类名();
调用成员的格式:
对象名.成员变量
对象名.成员方法();
示例代码 :
类的使用
public class TestStudent {
/*
创建对象的格式:
类名 对象名 = new 类名();
调用成员变量的格式:
对象名.变量名
调用成员方法的格式:
对象名.方法名();
*/
public static void main(String[] args) {
// 类名 对象名 = new 类名();
Student stu = new Student();
// 对象名.变量名
// 默认初始化值
System.out.println(stu.name); // null
System.out.println(stu.age); // 0
stu.name = "张三";
stu.age = 23;
System.out.println(stu.name); // 张三
System.out.println(stu.age); // 23
// 对象名.方法名();
stu.study();
// com.itheima.object1.Student@b4c966a
// 全类名(包名 + 类名)
System.out.println(stu);
}
}
对象内存图
单个对象内存图
多个对象内存图
总结:
多个对象在堆内存中,都有不同的内存划分,成员变量存储在各自的内存区域中,成员方法多个对象共用的一份
JAVA 虚拟机内存模型概念
虚拟机栈(简称:栈)的特点如下:
1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
2. JVM 为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)
3. 栈属于线程私有,不能实现线程间的共享!
4. 栈的存储特性是“先进后出,后进先出”
5. 栈是由系统自动分配,速度快!栈是一个连续的内存空间!
堆的特点如下:
1. 堆用于存储创建好的对象和数组(数组也是对象)
2. JVM 只有一个堆,被所有线程共享
3. 堆是一个不连续的内存空间,分配灵活,速度慢!
4. 堆被所有的线程所共享,在堆上的区域,会被垃圾回收器做进一步划分,例如新生代、老年代的划分。
方法区(也是堆)特点如下:
1. 方法区是 JAVA 虚拟机规范,可以有不同的实现。
i. JDK7 以前是“永久代”
ii. JDK7 部分去除“永久代”,静态变量、字符串常量池都挪到了堆内存中
iii. JDK8 是“元数据空间”和堆结合起来。
2. JVM 只有一个方法区,被所有线程共享!
3. 方法区实际也是堆,只是用于存储类、常量相关的信息!
4. 用来存放程序中永远是不变或唯一的内容。(类信息【Class 对象,反射机制中会重点讲授】、静态变量、字符串常量等)
5. 常量池主要存放常量:如文本字符串、final 常量值。
多个对象指向相同内存图
总结 :
当多个对象的引用指向同一个内存空间(变量所记录的地址值是一样的)
只要有任何一个对象修改了内存中的数据,随后,无论使用哪一个对象进行数据获取,都是修改后的数据。
成员变量和局部变量
成员变量和局部变量的区别
- 类中位置不同:成员变量(类中方法外)局部变量(方法内部或方法声明上)
- 内存中位置不同:成员变量(堆内存)局部变量(栈内存)
- 生命周期不同:成员变量(随着对象的存在而存在,随着对象的消失而消失)局部变量(随着方法的调用而存在,醉着方法的调用完毕而消失)
- 初始化值不同:成员变量(有默认初始化值)局部变量(没有默认初始化值,必须先定义,赋值才能使用)
垃圾回收原理和算法
内存管理
Java 的内存管理很大程度就是:堆中对象的管理,其中包括对象空间的分配和释放。
对象空间的分配:使用 new 关键字创建对象即可
对象空间的释放:将对象赋值 null 即可
垃圾回收过程
任何一种垃圾回收算法一般要做两件基本事情:
1. 发现无用的对象
2. 回收无用对象占用的内存空间。
垃圾回收机制保证可以将“无用的对象”进行回收。
无用的对象指的就是没有任何变量引用该对象。Java 的垃圾回收器通过相关算法发现无用对象,并进行清除和整理。
垃圾回收相关算法
引用计数法
堆中的每个对象都对应一个引用计数器,当有引用指向这个对象时,引用计数器加1,而当指向该对象的引用失效时(引用变为 null),引用计数器减 1,最后如果该对象的引用计算器的值为 0 时,则 Java 垃圾回收器会认为该对象是
无用对象并对其进行回收。优点是算法简单,缺点是“循环引用的无用对象”无法别识别。
this 关键字
普通方法中,this 总是指向调用该方法的对象。
构造方法中,this 总是指向正要初始化的对象。
this()调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。
this 不能用于 static 方法中。
this 是作为普通方法的“隐式参数”,由系统传入到方法中。
this的用法详解
public class TestThis {
int a, b, c;
TestThis() {
System.out.println("正要初始化一个Hello对象");
}
TestThis(int a, int b) {
// TestThis(); //这样是无法调用构造方法的!
this(); // 调用无参的构造方法,并且必须位于第一行!
a = a;// 这里都是指的局部变量而不是成员变量
// 这样就区分了成员变量和局部变量. 这种情况占了this使用情况大多数!
this.a = a;
this.b = b;
}
TestThis(int a, int b, int c) {
this(a, b); // 调用带参的构造方法,并且必须位于第一行!
this.c = c;
}
void sing() {
}
void eat() {
this.sing(); // 调用本类中的sing();
System.out.println("你妈妈喊你回家吃饭!");
}
public static void main(String[] args) {
TestThis hi = new TestThis(2, 3);
hi.eat();
}
}
this内存原理
注意 : this代表当前调用方法的引用,哪个对象调用的方法,this就代表哪一个对象
static 关键字
静态变量/静态方法生命周期和类相同,在整个程序执行期间都有效。它有如下特点:
为该类的公用变量,属于类,被该类的所有实例共享,在类载入时被初始化。
static 变量只有一份。
一般用“类名.类变量/方法”来调用。
在 static 方法中不可直接访问非 static 的成员。
static 关键字的使用
public class TestStatic {
int id; // id
String name; // 账户名
String pwd; // 密码
static String company = "北京xxx"; // 公司名称
public TestStatic(int id, String name) {
this.id = id;
this.name = name;
}
public void login() {
System.out.println(name);
}
public static void printCompany() {
// login();//调用非静态成员,编译就会报错
System.out.println(company);
}
public static void main(String[] args) {
TestStatic u = new TestStatic(101, "高xx");
TestStatic.printCompany();
TestStatic.company = "北京阿里";
TestStatic.printCompany();
}
}
静态初始化块
构造方法用于对象的普通属性初始化。
静态初始化块,用于类的初始化操作,初始化静态属性。
在静态初始化块中不能直接访问非 static 成员。
static 静态初始化块
public class TestStatic2 {
static String company; // 公司名称
static {
System.out.println("执行类的初始化工作");
company = "北京xxx";
printCompany();
}
public static void printCompany() {
System.out.println(company);
}
public static void main(String[] args) {
}
}
包机制(package、import)
包(package)相当于文件夹对于文件的作用。用于管理类、用于解决类的重名问题。
package 的使用有两个要点
1. 通常是类的第一句非注释性语句。
2. 包名:域名倒着写即可,便于内部管理类。
com.oracle.test;
com.itbaizhan.gao.test;
com.itbaizhan.gao.view;
JDK 中的主要包
导入类 import
如果要使用其他包的类,需使用 import,从而在本类中直接通过类名来调用,否则就需要书写类的完整包名和类名。
Java 会默认导入 java.lang 包下所有的类,因此这些类我们可以直接使用。
如果导入两个同名的类,只能用包名+类名来显示调用相关类:
java.util.Date date = new java.util.Date()
静态导入
静态导入(static import): 其作用是用于导入指定类的静态属性和静态方法,这样我们可以直接使用静态属性和静态方法。
静态导入的使用
package com.itbaizhan;
import static java.lang.Math.*;//导入Math类的所有静态属性
import static java.lang.Math.PI;//导入Math类的PI属性
public class Test2 {
public static void main(String[] args) {
System.out.println(PI);
System.out.println(random());
}
}
本文来自博客园,作者:link-零,转载请注明原文链接:https://www.cnblogs.com/e-link/p/16703205.html❤❤❤
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人