本文章参考B站 Java入门基础视频教程,java零基础自学首选黑马程序员Java入门教程(含Java项目和Java真题),仅供个人学习使用,部分内容为本人自己见解,与黑马程序员无关。

1、面向对象编程 (Object Oriented Programming)

1.1、面向对象

简单来说,面向对象就是找东西(找对象),设计东西(设计对象)过来解决问题(编程)

代码演示

public class Car {// 属性(成员变量)String name; // 名称double price; // 价格// 行为(方法)public void start(){System.out.println(name + " 价格是:" + price +", 启动成功!");}public void run(){System.out.println(name + " 价格是:" + price +", 跑的很快!");}
}
/**目标:掌握自己设计类,并获得对象。*/
public class Test {public static void main(String[] args) {// 如何去获取汽车的对象。Car c1 = new Car();System.out.println(c1);c1.name = "宝马5系";c1.price = 37.89;System.out.println(c1.name);System.out.println(c1.price);c1.start();c1.run();System.out.println("-------------------");Car c2 = new Car();System.out.println(c2);c2.name = "奔驰E系";c2.price = 39.89;System.out.println(c2.name);System.out.println(c2.price);c2.start();c2.run();}
}

输出结果:

com.itheima.createobject.Car@1b6d3586
宝马5系
37.89
宝马5系 价格是:37.89, 启动成功!
宝马5系 价格是:37.89, 跑的很快!
-------------------
com.itheima.createobject.Car@4554617c
奔驰E系
39.89
奔驰E系 价格是:39.89, 启动成功!
奔驰E系 价格是:39.89, 跑的很快!

1.2、对象内存图

多个对象的内存图

  1. 对象放在哪个位置?
  • 堆内存中
  1. Car c = new Car(); c变量名中存储的是什么?
  • 存储的是对象在堆内存中的地址。
  1. 成员变量(name、price)的数据放在哪里,存在于哪个位置?
  • 对象中,存在于堆内存中。

代码演示

public class Car {// 属性(成员变量)String name; // 名称double price; // 价格// 行为(方法)public void start(){System.out.println(name + " 价格是:" + price +", 启动成功!");}public void run(){System.out.println(name + " 价格是:" + price +", 跑的很快!");}
}
/**目标:掌握自己设计类,并获得对象。*/
public class Test {public static void main(String[] args) {// 如何去获取汽车的对象。Car c1 = new Car();System.out.println(c1);c1.name = "宝马X3";c1.price = 37.89;System.out.println(c1.name);System.out.println(c1.price);c1.start();c1.run();System.out.println("-------------------");Car c2 = new Car();System.out.println(c2);c2.name = "奔驰GLC";c2.price = 39.89;System.out.println(c2.name);System.out.println(c2.price);c2.start();c2.run();}
}

输出结果:

com.itheima.createobject.Car@1b6d3586
宝马X3
37.89
宝马X3 价格是:37.89, 启动成功!
宝马X3 价格是:37.89, 跑的很快!
-------------------
com.itheima.createobject.Car@4554617c
奔驰GLC
39.89
奔驰GLC 价格是:39.89, 启动成功!
奔驰GLC 价格是:39.89, 跑的很快!

两个变量指向同一个对象的内存图

代码演示

public class Student {String name;char sex;String hobby;public void study(){System.out.println("姓名:" + name +",性别是:" + sex+ ",爱好是:" + hobby + "的学生在好好学习,天天向上!");}
}
public class Test {public static void main(String[] args) {// 目标:掌握2个变量指向同一个对象的形式Student s1 = new Student();s1.name = "小明";s1.sex = '男';s1.hobby = "睡觉、游戏、听课";s1.study();// 关键:把s1赋值给学生类型的变量s2Student s2 =  s1;System.out.println(s1);System.out.println(s2);s2.hobby = "爱提问";System.out.println(s2.name);System.out.println(s2.sex);System.out.println(s1.hobby);s2.study();s1 = null;s2 = null;System.out.println(s1.name);}
}

输出结果:注意 s1.hobby 已经发生变化

姓名:小明,性别是:男,爱好是:睡觉、游戏、听课的学生在好好学习,天天向上!
com.itheima.memory.Student@1b6d3586
com.itheima.memory.Student@1b6d3586
小明
男
爱提问
姓名:小明,性别是:男,爱好是:爱提问的学生在好好学习,天天向上!
Exception in thread "main" java.lang.NullPointerExceptionat com.itheima.memory.Test.main(Test.java:26)Process finished with exit code 1

1.3、初探数组与集合

数组Array和集合的区别:

  1. 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型)
  2. JAVA集合可以存储和操作数目不固定的一组数据。
  3. 若程序时不知道究竟需要多少对象,需要在空间不足时自动扩增容量,则需要使用容器类库,array不适用。

补充:对象数组里面的每一个对象的值也是引用地址

1.4、构造器

通过构造器可以创建对象

代码演示

public class Car {String name;double price;/**无参数构造器(默认存在的)*/public Car(){System.out.println("无参数构造器被触发执行~~~");}/**有参数构造器*/public Car(String n, double p){System.out.println("有参数构造器被触发执行~~~");name = n;price = p;}
}
/**目标:明白构造器的作用和分类。(开发的人,理解能力好)*/
public class ConstructorDemo {public static void main(String[] args) {Car c = new Car();
//        c.name = "";
//        c.priceSystem.out.println(c.name);System.out.println(c.price);Car c2 = new Car("奔驰GLC", 39.78);System.out.println(c2.name);System.out.println(c2.price);}
}

输出结果:

无参数构造器被触发执行~~~
null
0.0
有参数构造器被触发执行~~~
奔驰GLC
39.78

1.5、this关键字


this:代表当前对象

代码演示

package com.itheima.test;public class Car {private String name;private double price;public Car() {System.out.println("无参构造器的this:" + this);}public void run() {System.out.println("方法run中的this:" + this);}public Car(String name, Double price) {System.out.println("有参构造器的this:" + this);this.name = name;this.price = price;}public void stop() {System.out.println("方法stop中的this:" + this);}
}
package com.itheima.test;public class Test {public static void main(String[] args) {Car car = new Car();System.out.println("car对象的地址:" + car);car.run();Car car1 = new Car("宝马5系", 48.88);System.out.println("car1对象的地址:" + car1);car1.stop();}}

输出结果:

无参构造器的this:com.itheima.test.Car@1b6d3586
car对象的地址:com.itheima.test.Car@1b6d3586
方法run中的this:com.itheima.test.Car@1b6d3586
有参构造器的this:com.itheima.test.Car@4554617c
car1对象的地址:com.itheima.test.Car@4554617c
方法stop中的this:com.itheima.test.Car@4554617c

没使用this的情况

public class Car {String name;double price;public Car(String name, Double price) {name = name;price = price;}}
public class Test {public static void main(String[] args) {Car car = new Car("宝马五系", 48.88);System.out.println(car.name);System.out.println(car.price);}}

输出结果:

null
0.0

可以发现名字相同的话是就就近赋值,把传过来的值赋值给自己,并没有修改对象的属性值

加了 this 后效果演示

package com.itheima.test;public class Car {String name;double price;public Car(String name, Double price) {this.name = name;this.price = price;}}
package com.itheima.test;public class Test {public static void main(String[] args) {Car car = new Car("宝马五系", 48.88);System.out.println(car.name);System.out.println(car.price);}}

输出结果:

宝马五系
48.88

this应用

public class Car {String name;double price;public Car(String name, Double price) {this.name = name;this.price = price;}public void runWith(String name) {System.out.println(name + "和" + name + "在比赛");System.out.println(this.name + "和" + name + "在比赛");}}
public class Test {public static void main(String[] args) {Car car = new Car("宝马五系", 48.88);car.runWith("奔驰E系");}}
奔驰E系和奔驰E系在比赛
宝马五系和奔驰E系在比赛

1.6、封装

面向对象三大特征:封装、继承、多态

对象代表什么,就得封装对应的数据,并提供数据对应的行为

  • 人画圆,画圆的方法应该在圆对象里面 (圆是圆自己画出来的,我们只是调用了画圆的方法)
  • 人关门,关门的方法应该在门对象里面(门是门自己关的,我们只是提供了作用力,相当于调用了关门的方法)

封装就是指将成员变量私有,提供方法暴露

封装的好处演示

public class Student {// private私有的成员变量,只能在本类访问。private int age;public int getAge(){return age;}public void setAge(int age){if(age >= 0 && age <= 200){this.age = age;}else {System.out.println("年龄数据有问题,应该不是人的年龄!");}}
}
/**目标:学会面向对象的三大特征:封装的形式、作用。*/
public class Test {public static void main(String[] args) {Student s = new Student();// s.age = -23;s.setAge(-23);System.out.println(s.getAge());}
}

输出结果:

年龄数据有问题,应该不是人的年龄!
0

1.7、JavaBean

1.8、成员变量、局部变量区别

2、常用API (String、ArrayList)

2.1、String

String 类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例。也就是说,Java 程序中所有的双引号字符串,都是 String 类的对象。String 类在 java.lang 包下,所以使用的时候不需要导包!

String 对象创建出来是不会改变的

2.1.1、创建 String 字符串的方式


代码演示

/**目标:String类创建字符串对象的2种方式*/
public class StringDemo2 {public static void main(String[] args) {// 方式一:直接使用双引号得到字符串对象String name = "我爱你中国";System.out.println(name);// 方式二:// 1、public String(): 创建一个空白字符串对象,不含有任何内容 (几乎不用)String s1 = new String(); // s1 = ""System.out.println(s1);// 2、public String(String): 根据传入的字符串内容,来创建字符串对象(几乎不用)String s2 = new String("我是中国人");System.out.println(s2);// 3、public String(char[] c): 根据字符数组的内容,来创建字符串对象char[] chars = {'a' , 'b' , '中', '国'};String s3 = new String(chars);System.out.println(s3);// 4、public String(byte[] b):  根据字节数组的内容,来创建字符串对象byte[] bytes = {97, 98, 99, 65, 66, 67};String s4 = new String(bytes);System.out.println(s4);System.out.println("---------------------------------------");String ss1 = "abc";String ss2 = "abc";System.out.println(ss1 == ss2);char[] chars1 = {'a' , 'b' , 'c'};String ss3 = new String(chars1);String ss4 = new String(chars1);System.out.println(ss3 == ss4);}
}

输出结果:

我爱你中国我是中国人
ab中国
abcABC
---------------------------------------
true
false

2.1.2、创建 String 字符串的内存原理 (常见面试题)

通过 “” 定义字符串内存原理

通过new构造器得到字符串对象内存原理

2.1.3、Java String 面试题



Java存在编译优化机制,程序在编译时: “a” + “b” + “c” 会直接转成 “abc”,原理可见编译后的 Class 文件

总结

总之,记住只有从常量池中取的才是相同的

2.1.4、String equals() 方法

字符串比较用 “equals” 比较,不能直接用 “",因为 "” 是判断地址的

  • String xx = “xx” 在常量池中定义

  • 用变量接收的字符串则在堆内存中

代码演示

public class StringAPIEqualsDemo4 {public static void main(String[] args) {// 1、正确登录名和密码String okName = "itheima";String okPassword = "123456";// 2、请您输入登录名称和密码Scanner sc = new Scanner(System.in);System.out.println("登录名称:");String name = sc.next();System.out.println("登录密码:");String password = sc.next();// 3、判断用户输入的登录名称和密码与正确的内容是否相等。if(okName.equals(name) && okPassword.equals(password)){System.out.println("登录成功!");}else {System.out.println("用户名或者密码错误了!");}// 4、忽略大小写比较内容的Api: 一般用于比较验证码这样的业务逻辑String sysCode = "23AdFh";String code1 = "23aDfH";System.out.println(sysCode.equals(code1)); // falseSystem.out.println(sysCode.equalsIgnoreCase(code1)); // true}
}

输出结果:

登录名称:
itheima
登录密码:
123456
登录成功!
false
true

拓展

基本类型比较才用 “==”

2.1.4、String 类常用方法

代码演示

/**目标:掌握String常用的其他API。*/
public class StringAPIOtherDemo5 {public static void main(String[] args) {// 1、public int length(): 获取字符串的长度String name = "我爱你中国love";System.out.println(name.length());// 2、public char charAt(int index): 获取某个索引位置处的字符char c = name.charAt(1);System.out.println(c);System.out.println("------------遍历字符串中的每个字符--------------");for (int i = 0; i < name.length(); i++) {char ch = name.charAt(i);System.out.print(ch + " ");}System.out.println();System.out.println("------------字符串转换成字符数组--------------");// 3、public char[] toCharArray():: 把字符串转换成字符数组char[] chars = name.toCharArray();for (int i = 0; i < chars.length; i++) {char ch = chars[i];System.out.print(ch + " ");}System.out.println();System.out.println("------------字符串截取内容--------------");// 4、public String substring(int beginIndex, int endIndex) :截取内容,(包前不包后的)String name2 = "Java是最厉害的编程语言!";//              01234567   89String rs = name2.substring(0, 9);System.out.println(rs);String rs1 = name2.substring(4, 9);System.out.println(rs1);// 5、public String substring(int beginIndex):从当前索引一直截取到末尾String rs2 = name2.substring(4);System.out.println(rs2);// 6、public String replace(CharSequence target, CharSequence replacement)String name3 = "Chovy是最厉害的90后,Chovy棒棒的!我好爱Chovy";String rs3 = name3.replace("Chovy", "***");System.out.println(rs3);// 7、public boolean contains(CharSequence s)System.out.println(name3.contains("Chovy")); // trueSystem.out.println(name3.contains("Chovy1")); // false// 8、public boolean startsWith(String prefix)System.out.println(name3.startsWith("Chovy"));System.out.println(name3.startsWith("Chovy是最厉害的"));System.out.println(name3.startsWith("Chovy是最厉害的2"));// 9、public String[] split(String s): 按照某个内容把字符串分割成字符串数组返回。String name4 = "IU,TaylorSwift,Krystal";String[] names = name4.split(",");for (int i = 0; i < names.length; i++) {System.out.println("选择了:" + names[i]);}}
}

输出结果:

9
爱
------------遍历字符串中的每个字符--------------
我 爱 你 中 国 l o v e
------------字符串转换成字符数组--------------
我 爱 你 中 国 l o v e
------------字符串截取内容--------------
Java是最厉害的
是最厉害的
是最厉害的编程语言!
***是最厉害的90后,***棒棒的!我好爱***
true
false
true
true
false
选择了:IU
选择了:TaylorSwift
选择了:Krystal

2.1.5、String 类使用案例

String类开发验证码功能

import java.util.Random;/**练习题:使用String完成随机生成5位的验证码。*/
public class StringExec6 {public static void main(String[] args) {// 1、定义可能出现的字符信息String datas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";// 2、循环5次,每次生成一个随机的索引,提取对应的字符连接起来即可String code = "";Random r = new Random();for (int i = 0; i < 5; i++) {// 随机一个索引int index = r.nextInt(datas.length());char c = datas.charAt(index);code += c;}// 3、输出字符串变量即可System.out.println(code);}
}

输出结果:

l6JUh

模拟用户登录功能

/**练习题:模拟用户登录*/
public class StringExec7 {public static void main(String[] args) {// 1、定义正确的登录名称和密码String okLoginName = "admin";String okPassword = "itheima";// 2、定义一个循环,循环3次,让用户登录Scanner sc = new Scanner(System.in);for (int i = 1; i <= 3; i++) {System.out.println("请您输入登录名称:");String loginName = sc.next();System.out.println("请您输入登录密码:");String password = sc.next();// 3、判断登录是否成功!if(okLoginName.equals(loginName)){// 4、判断密码是否正确if(okPassword.equals(password)){System.out.println("登录成功!欢迎进入系统随意浏览~~~~");break;}else {// 密码错误了System.out.println("您的密码不正确!您还剩余" + (3 - i) +"次机会登录!");}}else {System.out.println("您的登录名称不正确!您还剩余" + (3 - i) +"次机会登录!");}}}}

输出结果:

请您输入登录名称:
admin1
请您输入登录密码:
123456
您的登录名称不正确!您还剩余2次机会登录!
请您输入登录名称:
admin
请您输入登录密码:
123456
您的密码不正确!您还剩余1次机会登录!
请您输入登录名称:
admin
请您输入登录密码:
itheima
登录成功!欢迎进入系统随意浏览~~~~

手机号码屏蔽

import java.util.Scanner;/**练习题:手机号码屏蔽*/
public class StringExec8 {public static void main(String[] args) {// 1、键盘录入一个手机号码Scanner sc = new Scanner(System.in);System.out.println("请您输入您的手机号码:");String tel = sc.next();// 2、截取号码的前三位,后四位    18665666520String before = tel.substring(0, 3); // 0  1  2String after = tel.substring(7);  // 从索引7开始截取到手机号码的末尾String s = before + "****" + after;System.out.println(s);}
}

输出结果:

请您输入您的手机号码:
18665666520
186****6520

2.2、ArrayList

2.2.1、数组和 ArrayList的区别

1、数组和集合的元素存储的个数问题?

  • 数组定义后类型确定,长度固定
  • 集合类型可以不固定,大小是可变的。

2、数组和集合适合的场景

  • 数组适合做数据个数和类型确定的场景

  • 集合适合做数据个数不确定,且要做增删元素的场景

重点:数组跟 ArrayList 变量里面存的都是引用地址,只是获取的时候Java做了优化。

2.2.2、ArrayList 类入门 (构建ArrayList)

import java.util.ArrayList;**目标: 创建ArrayList对象,代表集合容器,往里面添加元素。*/
public class ArrayListDemo1 {public static void main(String[] args) {// 1、创建ArrayList集合的对象ArrayList list = new ArrayList();// 2、添加数据list.add("Java");list.add("Java");list.add("MySQL");list.add("黑马");list.add(23);list.add(23.5);list.add(false);System.out.println(list.add('中'));System.out.println(list);// 3、给指定索引位置插入元素list.add(1, "赵敏");System.out.println(list);}
}

输出结果:

true
[Java, Java, MySQL, 黑马, 23, 23.5, false, 中]
[Java, 赵敏, Java, MySQL, 黑马, 23, 23.5, false, 中]

2.2.3、ArrayList 类对于泛型的支持

import java.util.ArrayList;/**目标: 能够使用泛型约束ArrayList集合操作的数据类型*/
public class ArrayListDemo2 {public static void main(String[] args) {// ArrayList<String> list = new ArrayList<String>();ArrayList<String> list = new ArrayList<>(); // JDK 1.7开始,泛型后面的类型申明可以不写list.add("Java");list.add("MySQL");// list.add(23);// list.add(23.5);ArrayList<Integer> list2 = new ArrayList<>();list2.add(23);list2.add(100);// list2.add("Java");}
}

泛型:

Java泛型是J2 SE1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter)这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

2.2.4、ArrayList 类常用方法

代码演示

import java.util.ArrayList;/**目标:掌握ArrayList集合的常用API*/
public class ArrayListDemo3 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("Java");list.add("Java");list.add("MySQL");list.add("MyBatis");list.add("HTML");// 1、public E get(int index):获取某个索引位置处的元素值String e = list.get(3);System.out.println(e);// 2、public int size():获取集合的大小(元素个数)System.out.println(list.size());// 3、完成集合的遍历for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}// 4、public E remove(int index):删除某个索引位置处的元素值,并返回被删除的元素值System.out.println(list); // [Java, Java, MySQL, MyBatis, HTML]String e2 = list.remove(2);System.out.println(e2);System.out.println(list);// 5、public boolean remove(Object o):直接删除元素值,删除成功返回true,删除失败返回falseSystem.out.println(list.remove("MyBatis"));System.out.println(list);ArrayList<String> list1 = new ArrayList<>();list1.add("Java");list1.add("C#");list1.add("Java");list1.add("MySQL");System.out.println(list1);// 只会删除第一次出现的这个元素值,后面的不删除System.out.println(list1.remove("Java"));System.out.println(list1);// 6、public E set(int index,E element):修改某个索引位置处的元素值。String e3 = list1.set(0 , "C++");System.out.println(e3);System.out.println(list1);}
}

输出结果:

MyBatis
5
Java
Java
MySQL
MyBatis
HTML
[Java, Java, MySQL, MyBatis, HTML]
MySQL
[Java, Java, MyBatis, HTML]
true
[Java, Java, HTML]
[Java, C#, Java, MySQL]
true
[C#, Java, MySQL]
C#
[C++, Java, MySQL]

2.2.5、ArrayList 类使用案例

遍历并删除元素值(从后往前扫描)

import java.util.ArrayList;/**案例:从集合中遍历元素且删除。*/
public class ArrayListTest4 {public static void main(String[] args) {// 1、创建集合对象:存入学生成绩(98,77,66,89,79,50,100)ArrayList<Integer> scores = new ArrayList<>();scores.add(98);scores.add(77);scores.add(66);scores.add(89);scores.add(79);scores.add(50);scores.add(100);System.out.println(scores);// [98, 77, 66, 89, 79, 50, 100]// [98, 66, 89, 50, 100]//                   i// 1、遍历集合中的每个元素
//        for (int i = 0; i < scores.size(); i++) {//            int score = scores.get(i);
//            // 2、判断这个分数是否低于80分,如果低于则从集合中删除它
//            if(score < 80){//                scores.remove(i); // 此处删完应该执行 i--
//            }
//        }
//        System.out.println(scores);// [98, 77, 66, 89, 79, 50, 100]// [98,  89, 100]//   ifor (int i = scores.size() - 1; i >= 0 ; i--) {int score = scores.get(i);// 2、判断这个分数是否低于80分,如果低于则从集合中删除它if(score < 80){scores.remove(i);}}System.out.println(scores);}
}

输出结果:

[98, 77, 66, 89, 79, 50, 100]
[98, 89, 100]

注意:应该从后往前扫描,如果要从前往后扫描,在移除元素后应该执行 “i–”

存储自定义类型的对象 (结合数组)

  • 集合


直接输出集合是一串内存地址

System.out.println(movies);
// [com.itheima.arraylist.Movie@1b6d3586, com.itheima.arraylist.Movie@4554617c, com.itheima.arraylist.Movie@74a14482]
  • 数组

学生信息系统的数据搜索

public class Student {private String studyId;private String name;private int age;private String className;public Student() {}public Student(String studyId, String name, int age, String className) {this.studyId = studyId;this.name = name;this.age = age;this.className = className;}public String getStudyId() {return studyId;}public void setStudyId(String studyId) {this.studyId = studyId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}
}
import java.util.ArrayList;
import java.util.Scanner;/**案例:学生信息系统:展示数据,并按照学号完成搜索学生类信息(学号,姓名,性别,班级)测试数据:"20180302","叶孤城",23,"护理一班""20180303","东方不败",23,"推拿二班""20180304","西门吹雪",26,"中药学四班""20180305","梅超风",26,"神经科2班"*/
public class ArrayListTest6 {public static void main(String[] args) {// 1、定义一个学生类,后期用于创建对象封装学生数据// 2、定义一个集合对象用于装学生对象ArrayList<Student> students = new ArrayList<>();students.add(new Student("20180302","叶孤城",23,"护理一班"));students.add(new Student("20180303","东方不败",23,"推拿二班"));students.add(new Student( "20180304","西门吹雪",26,"中药学四班"));students.add(new Student( "20180305","梅超风",26,"神经科2班"));System.out.println("学号\t\t名称\t年龄\t\t班级");// 3、遍历集合中的每个学生对象并展示其数据for (int i = 0; i < students.size(); i++) {Student s = students.get(i);System.out.println(s.getStudyId() +"\t\t" + s.getName()+"\t\t"+ s.getAge() +"\t\t" + s.getClassName());}// 4、让用户不断的输入学号,可以搜索出该学生对象信息并展示出来(独立成方法)Scanner sc = new Scanner(System.in);while (true) {System.out.println("请您输入要查询的学生的学号:");String id = sc.next();Student s = getStudentByStudyId(students, id);// 判断学号是否存在if(s == null){System.out.println("查无此人!");}else {// 找到了该学生对象了,信息如下System.out.println(s.getStudyId() +"\t\t" + s.getName()+"\t\t"+ s.getAge() +"\t\t" + s.getClassName());}}}/**根据学号,去集合中找出学生对象并返回。* @param students* @param studyId* @return*/public static Student getStudentByStudyId(ArrayList<Student> students, String studyId){for (int i = 0; i < students.size(); i++) {Student s = students.get(i);if(s.getStudyId().equals(studyId)){return s;}}return null; // 查无此学号!}
}

输出结果:

学号       名称  年龄      班级
20180302        叶孤城     23      护理一班
20180303        东方不败        23      推拿二班
20180304        西门吹雪        26      中药学四班
20180305        梅超风     26      神经科2班
请您输入要查询的学生的学号:
20180302
20180302        叶孤城     23      护理一班
请您输入要查询的学生的学号:
20180307
查无此人!
请您输入要查询的学生的学号:

3、Java 项目:ATM系统

此项目可以深刻理解面向对象、参数传递、定义方法的好处

定义账户类

/**系统的账户类,代表账户的信息*/
public class Account {private String cardId; // 卡号private String userName; // 用户名称private String passWord; // 密码private double money; // 账户余额private double quotaMoney; // 每次取现额度限度。public String getCardId() {return cardId;}public void setCardId(String cardId) {this.cardId = cardId;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getPassWord() {return passWord;}public void setPassWord(String passWord) {this.passWord = passWord;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}public double getQuotaMoney() {return quotaMoney;}public void setQuotaMoney(double quotaMoney) {this.quotaMoney = quotaMoney;}
}

ATM 系统基本业务实现

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;public class ATMSystem {public static void main(String[] args) {// 2、创建一个集合对象,用于后期存入账户对象。ArrayList<Account> accounts = new ArrayList<>();// 3、展示系统欢迎页面System.out.println("======欢迎您进入到黑马ATM系统===============");while (true) {System.out.println("1、登录账户");System.out.println("2、注册账户");System.out.println("请您选择操作:");Scanner sc = new Scanner(System.in);int command = sc.nextInt();switch (command){case 1:// 登录操作login(accounts, sc);break;case 2:// 注册账户register(accounts, sc);break;default:System.out.println("当前输入的操作不存在!");}}}/**用户登录功能*/private static void login(ArrayList<Account> accounts, Scanner sc) {System.out.println("==================欢迎您进入到登录操作======================");if(accounts.size() > 0){while (true) {System.out.println("请您输入登录的卡号:");String cardId = sc.next();// 2、根据卡号去集合中查询是否存在账户对象Account acc = getAccountByCardId(cardId , accounts);// 判断账户对象是否存在,存在说明卡号正确if(acc != null){while (true) {// 3、判断密码是否正确System.out.println("请您输入登录的密码:");String passWord = sc.next();if(acc.getPassWord().equals(passWord)){// 登录成功了!System.out.println("欢迎你:" + acc.getUserName() + "先生/女士进入系统,您可开始办理你的业务了!");// 展示登录成功后的操作界面。showCommand(sc, acc, accounts);return;}else {System.out.println("您的密码不正确!");}}}else {System.out.println("卡号不存在,请确认!");}}}else {System.out.println("当前系统无任何账户,请先注册再登录!");}}/**登录后展示的界面*/private static void showCommand(Scanner sc, Account acc, ArrayList<Account> accounts) {while (true) {System.out.println("==================欢迎您进入到操作界面======================");System.out.println("1、查询");System.out.println("2、存款");System.out.println("3、取款");System.out.println("4、转账");System.out.println("5、修改密码");System.out.println("6、退出");System.out.println("7、注销账户");System.out.println("请您输入操作命令:");int command = sc.nextInt();switch (command) {case 1:// 查询账户信息展示showAccount(acc);break;case 2:// 存款depositMoney(acc,sc);break;case 3:// 取款drawMoney(acc,sc);break;case 4:// 转账transferMoney(acc, accounts, sc);break;case 5:// 修改密码updatePassWord(acc, sc);return; // 跳出当前操作的方法,最终回到首页case 6:// 退出 回到首页System.out.println("欢迎下次继续光临!!");return; // 结束登录后的全部操作case 7:// 注销账户accounts.remove(acc); // 从集合对象中删除当前账户对象。System.out.println("您的账户已经完成了销毁,您将不可以进行登录了!");return;default:System.out.println("您的操作命令有误!");}}}/**修改当前账户对象的密码* @param acc*/private static void updatePassWord(Account acc, Scanner sc) {// 1、判断旧密码是否正确while (true) {System.out.println("请您输入当前密码认证:");String passWord = sc.next();if(acc.getPassWord().equals(passWord)){while (true) {// 2、输入新密码System.out.println("请您输入新密码:");String newPassWord = sc.next();System.out.println("请您确认新密码:");String okPassWord = sc.next();// 3、比对两次密码是否一致if(newPassWord.equals(okPassWord)){acc.setPassWord(okPassWord);System.out.println("密码已经修改成功,请重新登录!");return;}else {System.out.println("两次密码不一致!");}}}else {System.out.println("您输入的密码有误。请重新确认密码!");}}}/*** 从当前账户对象中把金额转给其他账户对象。* @param acc* @param accounts* @param sc*/private static void transferMoney(Account acc, ArrayList<Account> accounts, Scanner sc) {// 1、判断自己的账户中是否有钱if(acc.getMoney() <= 0){System.out.println("您自己都没钱,就别转了吧!");return;}// 2、判断总账户数量是否大于等于2个。if(accounts.size() >= 2){while (true) {// 3、让当前用户输入对方的账号进行转账System.out.println("请您输入对方卡号:");String cardId = sc.next();// 4、根据卡号查询出集合中的账户对象Account otherAcc = getAccountByCardId(cardId , accounts);// 5、判断账户对象是否存在,而且这个账户对象不能是自己。if(otherAcc != null){// 6、判断当前账户是否是自己。if(acc.getCardId().equals(otherAcc.getCardId())){System.out.println("不能给自己账户转账!");}else {// 7、正式进入到转账逻辑了// 黑马刘德华String rs = "*" + otherAcc.getUserName().substring(1);System.out.println("请您确认["+rs +"]的姓氏来确认!");System.out.println("请您输入对方的姓氏:");String preName = sc.next();if(otherAcc.getUserName().startsWith(preName)){// 认证通过while (true) {System.out.println("请您输入转账的金额(您最多可以转账:" + acc.getMoney() +"元):");double money = sc.nextDouble();if(money > acc.getMoney()){System.out.println("你不听话,没有这么多钱可以转!");}else {// 开始转acc.setMoney(acc.getMoney() - money); // 更新自己账户otherAcc.setMoney(otherAcc.getMoney() + money);System.out.println("您已经完成转账!您当前还剩余:" + acc.getMoney());return;}}}else {System.out.println("您输入对方的信息有误!");}}}else {System.out.println("您输入的转账卡号不存在!");}}}else {System.out.println("当前系统中没有其他账户可以转账,去注册一个账户吧!");}}private static void drawMoney(Account acc, Scanner sc) {System.out.println("==================欢迎进入账户取款操作======================");// 1、判断账户的余额是否高于等于100double money = acc.getMoney();if(money >= 100) {while (true) {// 2、输入取钱的金额System.out.println("请您输入取钱的金额:");double drawMoney = sc.nextDouble();// 3、判断取钱金额是否超过了当次限额if(drawMoney > acc.getQuotaMoney()){System.out.println("您当前取款金额超过了每次限额!");}else {// 4、判断当前取钱金额是超过了账户的余额if(drawMoney > money){System.out.println("当前余额不足!当前余额是:" + money);}else {// 更新账户余额acc.setMoney(money - drawMoney);System.out.println("您当前取钱完成,请拿走你的钱,当前剩余余额是:" + acc.getMoney());break;}}}}else {System.out.println("您当前账户余额不足100元,存钱去吧!");}}private static void depositMoney(Account acc, Scanner sc) {System.out.println("==================欢迎进入账户存款操作======================");System.out.println("请您输入存款金额:");double money = sc.nextDouble();acc.setMoney(acc.getMoney() + money);showAccount(acc);}private static void showAccount(Account acc) {System.out.println("==================您当前账户详情信息如下======================");System.out.println("卡号:" + acc.getCardId());System.out.println("户主:" + acc.getUserName());System.out.println("余额:" + acc.getMoney());System.out.println("当次取现额度:" + acc.getQuotaMoney());}/**开户功能*/private static void register(ArrayList<Account> accounts, Scanner sc) {System.out.println("==================欢迎您进入到开户操作======================");// 2、创建一个账户对象封装账户信息Account acc = new Account();// 1、录入用户账户信息System.out.println("请您输入账户名称:");String userName =sc.next();acc.setUserName(userName);while (true) {System.out.println("请您输入账户密码:");String passWord =sc.next();System.out.println("请您输入确认密码:");String okPassWord =sc.next();if(okPassWord.equals(passWord)){// 密码无问题acc.setPassWord(okPassWord);break;}else {System.out.println("两次输入的密码不一致!");}}System.out.println("请您设置当次取现额度:");double quataMoney = sc.nextDouble();acc.setQuotaMoney(quataMoney);// 关键点:为当前账户生成一个随机的8位数字作为卡号,卡号不能与其他用户的卡号重复。String cardId = createCardId(accounts);acc.setCardId(cardId);// 3、把账户对象存入到集合容器对象中去accounts.add(acc);System.out.println("恭喜您,"+acc.getUserName()+"先生/女士,您开户完成,您的卡号是:" + acc.getCardId());}public static String createCardId(ArrayList<Account> accounts){while (true) {String cardId = "";// 随机8个数字Random r = new Random();for (int i = 1; i <= 8 ; i++) {cardId += r.nextInt(10);}// 判断这个卡号是否重复:根据卡号去查询账户对象Account account = getAccountByCardId(cardId , accounts);if(account == null){return cardId;}}}public static Account getAccountByCardId(String cardId , ArrayList<Account> accounts){for (int i = 0; i < accounts.size(); i++) {Account acc = accounts.get(i);if(acc.getCardId().equals(cardId)){return acc;}}return null;}
}

4、static 关键字

4.1、 static 的作用、修饰成员变量的用法

static关键字的作用

  • static 是静态的意思,可以修饰成员变量和成员方法。

  • static 修饰成员变量表示该成员变量只在内存中只存储一份,可以被共享访问、修改。

  • 非 static 修饰成员变量是属于对象的,需要创建对象才能使用

成员变量

代码演示

public class User {// 在线人数信息:静态成员变量public static int onLineNumber = 161;// 实例成员变量private String name;private int age;public static void main(String[] args) {// 1、类名.静态成员变量User.onLineNumber++;// 注意:同一个类中访问静态成员变量,类名可以省略不写System.out.println(onLineNumber);// 2、对象.实例成员变量// System.out.println(name);User u1 = new User();u1.name = "猪八戒";u1.age = 36;System.out.println(u1.name);System.out.println(u1.age);// 对象.静态成员变量(不推荐这样访问)u1.onLineNumber++;User u2 = new User();u2.name = "孙悟空";u2.age = 38;System.out.println(u2.name);System.out.println(u2.age);// 对象.静态成员变量(不推荐这样访问)u2.onLineNumber++;System.out.println(onLineNumber);}
}

输出结果:

162
猪八戒
36
孙悟空
38
164

内存原理:

总结

  1. 成员变量的分类和访问分别是什么样的?
  • 静态成员变量(有static修饰,属于类、加载一次,可以被共享访问)

  • 实例成员变量(无static修饰,属于对象):

  1. 两种成员变量各自在什么情况下定义?
  • 静态成员变量:表示在线人数等需要被共享的信息。

  • 实例成员变量:属于每个对象,且每个对象信息不同时(name,age,…等)

4.2、static修饰成员方法的基本用法

成员方法的分类

  • 静态成员方法(有static修饰,属于类),建议用类名访问,也可以用对象访问。

  • 实例成员方法(无static修饰,属于对象),只能用对象触发访问。

使用场景

  • 表示对象自己的行为的,且方法中需要访问实例成员的,则该方法必须申明成实例方法。

  • 如果该方法是以执行一个共用功能为目的,则可以申明成静态方法。

代码演示

public class Student {private String name;private int age;/**实例方法:无static修饰,属于对象的,通常表示对象自己的行为,可以访问对象的成员变量*/public void study(){System.out.println(name + "在好好学习,天天向上~~");}/**静态方法:有static修饰,属于类,可以被类和对象共享访问。*/public static void getMax(int a, int b){System.out.println(a > b ? a : b);}public static void main(String[] args) {// 1、类名.静态方法Student.getMax(10, 100);// 注意:同一个类中访问静态成员 可以省略类名不写getMax(200, 20);// 2、对象.实例方法// study(); // 报错的Student s = new Student();s.name = "全蛋儿";s.study();// 3、对象.静态方法(不推荐)s.getMax(300,20);}
}

输出结果:

100
200
全蛋儿在好好学习,天天向上~~
300

内存原理

4.3、工具类

  • 工具类中定义的都是一些静态方法,每个方法都是以完成一个共用的功能为目的
  • 工具类的好处:一是调用方便,二是提高了代码复用(一次编写,处处可用)

验证码工具类

public class VerifyTool {/**私有构造器*/private VerifyTool(){}/**静态方法*/public static String createCode(int n){// 1、使用String开发一个验证码String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";// 2、定义一个变量用于存储5位随机的字符作为验证码String code = "";// 3、循环Random r = new Random();for (int i = 0; i < n; i++) {int index = r.nextInt(chars.length());// 4、对应索引提取字符code += chars.charAt(index);}return code;}
}
public class Login {public static void main(String[] args) {// 验证码:System.out.println("验证码:" + VerifyTool.createCode(10));}
}
public class Register {public static void main(String[] args) {// 验证码:System.out.println("验证码:" + VerifyTool.createCode(5));}
}

数组工具类

public class ArrayUtils {/**把它的构造器私有化*/private ArrayUtils(){}/**静态方法,工具方法*/public static String toString(int[] arr){if(arr != null ){String result = "[";for (int i = 0; i < arr.length; i++) {result += (i == arr.length - 1 ? arr[i] : arr[i] + ", ");}result += "]";return result;}else {return null;}}/**静态方法,工具方法*/public static double getAverage(int[] arr){// 总和  最大值 最小值int max = arr[0];int min = arr[0];int sum = 0;for (int i = 0; i < arr.length; i++) {if(arr[i] > max){max = arr[i];}if(arr[i] < min){min = arr[i];}sum += arr[i];}return (sum - max - min)*1.0 / (arr.length - 2);}
}

测试

public class Test2 {public static void main(String[] args) {int[] arr = {10, 20, 30};System.out.println(arr);System.out.println(ArrayUtils.toString(arr));System.out.println(ArrayUtils.getAverage(arr));int[] arr1 = null;System.out.println(ArrayUtils.toString(arr1));int[] arr2 = {};System.out.println(ArrayUtils.toString(arr2));}
}

输出结果:

[I@1b6d3586
[10, 20, 30]
20.0
null
[]

工具类的定义注意

  • 建议将工具类的构造器进行私有,工具类无需创建对象。

  • 里面都是静态方法,直接用类名访问即可。

4.4、代码块

代码块概述

  • 代码块是类的5大成分之一(成员变量、构造器,方法,代码块,内部类),定义在类中方法外。

  • 在Java类下,使用 { } 括起来的代码被称为代码块

代码块分类

  1. 静态代码块:
  • 格式:static{}

  • 特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发、只执行一次

  • 使用场景:在类加载的时候做一些静态数据初始化的操作,以便后续使用。

  1. 构造代码块了解,用得少):
  • 格式:{}

  • 特点:每次创建对象,调用构造器执行时,都会执行该代码块中的代码,并且在构造器执行前执行

  • 使用场景:初始化实例资源。

静态代码块作用

  • 如果要在启动系统时对数据进行初始化。

  • 建议使用静态代码块完成数据的初始化操作,代码优雅。

静态代码块优先执行

public class TestDemo1 {public static String schoolName;public static void main(String[] args) {// 目标:学习静态代码块的特点、基本作用System.out.println("=========main方法被执行输出===========");System.out.println(schoolName);}/**特点:与类一起加载,自动触发一次,优先执行作用:可以在程序加载时进行静态数据的初始化操作(准备内容)*/static{System.out.println("==静态代码块被触发执行==");schoolName = "黑马程序员";}
}

输出结果:

==静态代码块被触发执行==
=========main方法被执行输出===========
黑马程序员

静态代码块应用

import java.util.ArrayList;public class StaticCodeTest3 {/**模拟初始化牌操作点数: "3","4","5","6","7","8","9","10","J","Q","K","A","2"花色: "♠", "♥", "♣", "♦"1、准备一个容器,存储54张牌对象,这个容器建议使用静态的集合。静态的集合只加载一次。*/// int age = 12;public static ArrayList<String> cards = new ArrayList<>();/**2、在游戏启动之前需要准备好54张牌放进去,使用静态代码块进行初始化*/static{// 3、加载54张牌进去。// 4、准备4种花色:类型确定,个数确定了String[] colors = {"♠", "♥", "♣", "♦"};// 5、定义点数String[] sizes = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};// 6、先遍历点数、再组合花色for (int i = 0; i < sizes.length; i++) {// sizes[i]for (int j = 0; j < colors.length; j++) {cards.add(sizes[i] + colors[j]);}}// 7、添加大小王cards.add("小												

Java进阶-面向对象相关推荐

  1. Java小白进阶笔记(5)-进阶面向对象

    继续学习: 7.偏头痛杨的Java入门教学系列之进阶面向对象篇 上Java课的时候没弄明白接口,今天终于明白了(但没使用过,还停在理论的程度,可能理解也不准确,以后学通了会回来补充:)如果你刚学Jav ...

  2. Java进阶学习-7 面向对象程序设计原则

    title: Java进阶学习-7 面向对象程序设计原则 date: 2020-02-02 18:02:27 tags: 以一个城堡游戏为例子谈面向对象程序设计原则 Game.java package ...

  3. Java进阶知识-数组类型

    前言 本来数组类型应该属于基础部分的知识,我将它写在进阶部分是因为数组既可以是基础数据类型数组,也可以是引用数据类型数组.所以我想先介绍完类与对象的基础之后,再给大家介绍数组.于是,今天这篇内容给大家 ...

  4. java进阶案例下载_java进阶案例

    java进阶案例: 数据类型,字符,数值,范围,布尔 :byte -128~127. 面向对象:protect :重载与构造 (一). this封装:static:继承:多态: 1.方法覆盖:supe ...

  5. Java进阶3. 内存回收机制

    Java进阶3. 内存回收机制 20131029 前言: 学过C++的都知道,C++中内存需要程序员自己维护.说道这里,很多开发的同学就感觉很痛苦,当他转向Java的时候,就会说你看Java多好啊,程 ...

  6. Java基础到Java进阶——Java小白的历练之路------从0到1,开卷!

    Java小白的历练之路------从0到1 title: Java Essay date: 2022-09-07 08:58:32 tags: Java notes 写在前面: 免责声明:本笔记来源自 ...

  7. Java 自学路线图之 Java 进阶自学

    文章目录 Java 自学路线图的第二阶段是 Java 语言进阶自学,在自学了第一阶段的 Java 基础自学后,大家对 Java 语言编程有了初步的了解和认识,建议在第一部分自学后整理一下自己的自学思路 ...

  8. 第十六讲 java进阶-API

    第十六讲 java进阶-重写equals方法的深度解读 1 接口的补充 接口为什么不能new对象?有没有必要new对象?或者是说如果能new对象,new出来的是什么东西?有什么内容,是否符合对象的特征 ...

  9. java进阶之匿名内部类,访问修饰符,包

    文章目录 一.形式参数和返回值 二.包 1.包 2.导包 三.权限修饰符 1.权限修饰符: 2.常见的权限修饰符 四.内部类 一.形式参数和返回值 (1)形式参数: 类名:需要该类的对象 抽象类名:需 ...

  10. 思维导图结构化梳理Java进阶方向

    思维导图结构化梳理Java进阶方向 写在前面 公众号的后台有读者给我留言说,对java每一阶段应该会什么技术感到迷茫.有个几年经验的爪娃们都经历过成长的阶段,但每个人成长阶段接触到的技术不尽相同.作为 ...

最新文章

  1. 国庆七天乐——第一天
  2. oracle goldengate报错解决之OGG-00446
  3. maven中如何将所有引用的jar包打包到一个jar中
  4. 全局统一返回结果包装信息
  5. grep参数说明及常用用法
  6. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题
  7. 互联网公司上演反腐风暴;GitHub CEO 对断供表示无能为力;程序员面试锦集| 开发者周刊...
  8. script片段在前导致对下文的html元素引用失效
  9. python做购物系统的实训报告_网上购物系统实训总结
  10. 计算机科学ppt模板,计算机科学与技术ppt模板
  11. YOLACT pytorch模型转tensorflow savedModel格式
  12. TRUNK理论与配置实验
  13. 基于Token的验证方式(JWT简笔)
  14. 再一次和新同事们谈谈看法
  15. 代码管理工具:Git
  16. HTML应用开发基础篇 - MUI 框架(三)MUI 布局
  17. HM10.1码率控制模块代码详解(1)---------序列级码率控制类TEncRCSeq介绍
  18. 从金蝶k3到金税盘_金蝶K3操作流程图详解
  19. C4d lite r 16语言包,[其他软件] C4D S22 三维软件Maxon Cinema 4D S22.016 C4D R22 含中文语言包 破译版(Win)...
  20. [ios学习入门3]--oc中NS的含义

热门文章

  1. 我的项目day04:首页,轮播图前后端,登录注册功能设计,cgi,uwsgi,多方式登录接口,手机号是否存在接口,腾讯云短信,模态框,腾讯短信功能二次封装,短信验证接口,短信注册接口,断行注册接口
  2. HTML基础常识问答(二)
  3. [UE4]风格化渲染
  4. XYNUOJ 第四次比赛 懒省事得小名
  5. 面向对象-当谈论面向对象的时候,我们到底在谈论什么?
  6. 用k-mer分析进行基因组调查:(六)用KmerGenie一步实现
  7. syslinux和grub引导linux,在Arch上使用Syslinux替代GRUB
  8. 若依框架登录去除验证码
  9. 贪心法找钱python_python找钱?
  10. HDU5745 La Vie en rose