Day5:面向对象的定义(中)
1、面向对象的特点------封装性
/* 封装:隐藏实现细节,对外提供公共的访问方式。 1,安全性。 2,复用性。 3,隔离的变化。后期应用于分层设计。 */ /* 描述人: 属性:姓名,年龄。 行为:说话。 */ class Person { private String name; private/*私有*/ int age; /* 将成员变量私有化,对外提供set get方法,对其访问的原因就是可以属性可控。 私有关键字private 是一个权限修饰符,只能修饰成员(成员变量,成员函数)。 注意:私有仅仅是封装的表现形式之一! */ public void setName(String s) { name = s; } public String getName() { return name; } public void setAge(int a) { /*可以加入健壮性的判断。 if(a<=0 || a>120) throw */ age = a; } public int getAge() { return age; } void speak() { System.out.println(name+":"+age); } } class PersonDemo { public static void main(String[] args) { Person p = new Person(); // p.name = "旺财"; // p.age = -20; p.setName("旺财"); p.setAge(20); p.speak(); } }
2、this关键字
/* this关键字。 1,区分局部变量和成员变量同名的情况。 用this标识的是成员变量。 this到底是个啥呢? this其实就代表对象,代表哪个对象呢? 哪个对象调用了this所在的函数。this就指向哪个对象。 (this就代表着当前这个对象) */ class Person { private String name; private int age; Person() { this.name = "baby"; System.out.println("Person() run..."); } Person(String name) { this.name = name;//局部变量和成员变量重名了。 System.out.println("person(name)...run..."); } Person(String name,int age) { this.name = name; this.age = age; System.out.println("person(n,a)....run...."); } public void show() { System.out.println(this.name+"...."+this.age); } public void method(int x) { this.show(); } } class ThisDemo { public static void main(String[] args) { Person p = new Person("李四"); p.show(); Person p1 = new Person("王武"); p1.method(); } }
/* this关键字的用法二: 构造函数间调用。this关键字。 用法格式:this(对应的实参列表); 注意:必须定义在构造函数的第一行,因为初始化动作要先执行。 构造间调用其实也是为了初始化的复用性。 不要出现互相调用,产生递归,容易栈溢出。 */ class Person { private String name; private int age; Person() { this.name = "baby"; System.out.println("Person() run..."); } Person(String name) { this.name = name; System.out.println("person(name)...run..."); } Person(String name,int age) { this(name);//用于调用构造函数。注意:调用构造函数的语句必须定义在构造函数的第一行! this.age = age; System.out.println("person(n,a)....run...."); } public void show() { System.out.println(this.name+"...."+this.age); } public void method() { this.show(); } } class ThisDemo2 { public static void main(String[] args) { Person p = new Person("李四",20); new Person(); } }
/* this在代码中的应用。 */ class Person { private int age; Person(int age) { this.age = age; } /* 定义一个功能,判断和别人是否是同龄人。 结果?boolean 参数?Person 功能内部如果用到了调用该功能的对象,用this代表这个对象。 */blic boolean equalsAge(Person p) pu{ return this.age == p.age; } } class ThisDemo3 { public static void main(String[] args) { Person p1 = new Person(32); Person p2 = new Person(23); boolean b = p1.equalsAge(p2); System.out.println("b="+b); } }
3、static关键字
/* static 关键字是一个成员修饰符。 static关键字的特点: 1,静态的数据被对象所共享。 2,它优先于对象加载并存在。 随着类的加载而加载。 3,静态的数据多了一种调用方式:可以直接被类名所调用。 既然静态调用这么方便,是不是可以让所有的成员变量变成静态的呢? 不行,因为数据中有些是对象共享的数据需要静态化,节省内存空间,严谨。 有些数据是对象特有的数据,这些存储到对象中。 这也是成员变量是否要静态的依据! 举例:教室里的饮水机和每个对象特有的杯子的故事! 静态变量和成员变量的区别? 名称(所属): 静态变量所属于类,也称为 类变量。 成员变量所属于对象,也称为 实例变量。 内存位置: 静态变量存储于方法区中的静态区中。 成员变量存储于堆内存的对象中。 加载先后: 静态变量随着类的加载而加载,随着类的消失而消失。 成员变量随着对象的加载而加载,随着对象的消失而消失。 */ class Person { String name; static String country = "cn"; } class StaticDemo { public static void main(String[] args) { Person p = new Person(); p.name = "lisi"; //静态的成员的调用。 System.out.println(Person.country); } }
/* 静态方法: 1,静态方法只能访问静态成员,不能直接访问非静态成员。 非静态的方法可以访问静态和非静态。 其实原因就是加载的先后顺序问题。先加载的不能访问后加载。 2,静态方法中不可以出现this,super关键字。 什么时候方法静态? 方法中如果没有访问对象的特有数据,或者说没有调用过非静态的内容。 该方法就静态化。虽然不静态也可以使用,但是创建调用它的对象没有意义。 */ class Person { String name; static String country = "cn"; static void show() { // System.out.println(this.name);//编译失败。 System.out.println(country); } static void method() { System.out.println(Person.country); } } class StaticDemo2 { public static void main(String[] args) { // new Person().show(); // Person.show(); // new Person().method(); Person.method(); } }
4、main方法
/* public static void main(String[] args) public : 权限修饰符,主方法的权限最大。 static : 随着类的加载而加载,直接被类名调用。 void : 主方法没有具体的返回值。 main : 方法名称,不是关键字,但是该名字固定。 String[] args : 方法的参数列表,一个字符串数组参数。args就是变量名。 */ class MainDemo { int x = 4; public static void main(String[] args) //args = new String[0]; { /* System.out.println(args.length);//[Ljava.lang.String;@19836ed for(int x=0; x<args.length; x++) { System.out.println(args[x]); } */ new MainDemo().show(); } void show() { System.out.println(x); } }
5、静态代码块
/* 静态代码块。 特点:随着类的加载而执行,而且只执行一次。 作用:用来给类进行初始化的。 */ class StaticCode { // static int x= 3; static { // x = 5; System.out.println("a"); } static void show() { System.out.println("show run"); } } class StaticCodeDemo { static { System.out.println("b"); } public static void main(String[] args) { StaticCode.show(); } static { System.out.println("c"); } }
6、对象的初始化过程
7、小练习
A、
class Person { private String name = "baby"; {//构造代码块作用,给所有的对象初始化。 System.out.println("code......"+this.name); cry(); } Person()//构造函数只给对应的对象初始化。 { // cry(); System.out.println("person() run...."); } Person(String name) { this.name = name; // cry(); System.out.println("person(name) run......"); } void cry() { System.out.println("哇哇......"); } } class CodeDemo { public static void main(String[] args) { Person p = new Person(); Person p1 = new Person("lisi"); {//局部代码块。控制局部变量的生命周期。 int x = 4; System.out.println("x="+x); } System.out.println("x="+x); System.out.println("over"); } }
B、
/* 综合练习,练习一下之前的小知识点。 主函数定义代码--->封装到函数中提高复用性---->将函数封装到对象中。 */ class ArrayToolDemo { public static void main(String[] args) { int[] arr = {34,120,78,45,90,33}; int max = ArrayTool.getMax(arr); int min = ArrayTool.getMin(arr); System.out.println("max="+max); System.out.println("min="+min); } }
C、
/** 这是一个用于操作数组的工具类,功能有获取最值,排序等一系列静态方法。 @author 张三 @version V1.0 */ public class ArrayTool { /** 构造函数。 */ public ArrayTool(){} /** 获取数组的最大值。 @param arr 接收的是一个int类型的数组。 @return 返回该数组的最大值。 */ public static int getMax(int[] arr) { int max = arr[0]; for(int x=1; x<arr.length; x++) { if(arr[x]>max) max = arr[x]; } return max; } /** 获取数组的最小值。 @param arr 接收的是一个int类型的数组。 @return 返回该数组的最小值。 */ public static int getMin(int[] arr) { int min = arr[0]; for(int x=1; x<arr.length; x++) { if(arr[x]<min) min = arr[x]; } return min; } /** 对整型数组进行从小到大的排序。 @param arr 接收的是一个int类型的数组。 */ public static void selectSort(int[] arr) { for (int x=0; x<arr.length-1 ;x++ ) { for (int y=x+1; y<arr.length ;y++ ) { if(arr[x]>arr[y]) { swap(arr,x,y); } } } } /** 对数组中的两个位置的元素进行置换。 @param arr 接收的是一个int类型的数组。 @param a 需要置换的元素的角标 @param b 需要置换的另一个元素的角标 */ private static void swap(int[] arr,int a,int b) { int temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· Vite CVE-2025-30208 安全漏洞
· 《HelloGitHub》第 108 期
· MQ 如何保证数据一致性?
· 一个基于 .NET 开源免费的异地组网和内网穿透工具