面向对象基础(黑马)
类与对象
类是对对象公有特征的描述
对象的不同是由属性来决定的,属性用来描述对象的特征,从后面对于equals方法重写用于对象的比较中可以发现,比较对象不同,具体比较各个属性是否相同,而不需要比较行为
类的几个补充注意事项
在定义javabean类时,不建议在定义类的时候给属性赋值,如果在定义属性的时候给属性赋值,以该类为模板创建出来的对象的该属性值都是这个值
因为这个类只是定义对象的公有行为,并不是单指哪个对象
对象成员默认值规则
开发中类的设计
**类的使用:在需求中提炼名词:将名词写成类 **
将验证学号这个功能提炼成行为,定义成方法
类的设计技巧:将名词设计成属性,将动词设计成方法
封装
人画原,调用的应该是圆的方法
门开门和关门,应该是门的行为,人只是调用了这个方法
导致封装问题的产生
就近原则和this关键字
当成员变量和局部变量重名的情况下,局部变量优先原则,如果非要要求调用成员变量,可以用this用于标识调用成员变量
构造方法
如果我们的类中没有写构造方法,我们的JVM将会给我们提供一个空参构造
构造方法注意事项
建议:不管在什么情况下都写上带空参和带有全部参数的构造方法
构造方法的作用扫盲
构造方法的作用并不是创建对象,创建对象是new关键字执行的,而构造方法的作用是给对象的属性(成员变量)进行初始化
标准javaBean类
- javaBean类的要求
对象的内存图
当类加载时其字节码文件将会临时储存在方法区
一个对象的内存图
类的加载会将该类的字节码文件加载到方法区中,方法区中将细致包括该类的成员变量和行为方法
将局部变量储存在栈空间,将要调用的方法储存在栈空间,按照后进先出的规则进行调用
创建对象将会开辟堆内存空间,在堆内存中将成员变量赋值一份,并将成员方法的地址拷贝一份,赋值成员方法的地址是为了我们以后用对象调用方法的时候可以找到我们的方法
两个对象的内存图
2个引用指向同一个对象
基本数据类型和引用数据类型的区别
基本数据类型储存的是真实的数据值
数组也是引用数据类型,以数组举例
this的内层原理
this的本质:代表方法调用者的地址值
成员变量和局部变量的区别
创建的对象如果没有变量去指向它,他将会变成垃圾,然后被回收
- Role类
package com.an.a;
import java.util.Random;
//文字版格斗版游戏角色类
public class Role {
private String name;//角色名称
private int blood;//角色血量
public Role() {
}
public Role(String name, int blood) {
this.name = name;
this.blood = blood;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return blood
*/
public int getBlood() {
return blood;
}
/**
* 设置
* @param blood
*/
public void setBlood(int blood) {
this.blood = blood;
}
//人物攻击行为
//方法的调用对象攻击参数对象
public void attack(Role role){
//this表示方法调用者
//用随机数表示造成的伤害
Random r = new Random();
int hurt = r.nextInt(20) + 1;
int remainBlood = role.getBlood()-hurt;
//保证其血量不会出现负数的异常情况
remainBlood = role.getBlood() - hurt <= 0 ? 0 : remainBlood;
role.setBlood(remainBlood);
System.out.println(this.name+"用拳头打了"+role.getName()+"一下, " +
"造成"+hurt+"点的伤害,"+role.getName()+"还剩下"+role.getBlood()+"点血量");
}
}
- 测试类
package com.an.a;
public class GameTest {
public static void main(String[] args) {
Role r1 = new Role("乔峰",100);
Role r2 = new Role("鸠摩智",100);
while(true){
//r1攻击r2
r1.attack(r2);
if(r2.getBlood()<=0){
System.out.println(r1.getName()+"KO了"+r2.getName());
break;
}
//r2攻击r1
r2.attack(r1);
if(r1.getBlood()<=0){
System.out.println(r2.getName()+"KO了"+r1.getName());
break;
}
}
}
}
按照以下的提示进行游戏的优化
- 对于角色形象的优化
package com.an.a;
import java.util.Random;
//文字版格斗版游戏角色类
public class Role {
private String name;//角色名称
private int blood;//角色血量
private char gender;//性别
private String face;//长相
String[]boyfances = {"风流俊雅","气宇轩昂","相貌英俊","相貌平平","青面獠牙","面目狰狞","不忍直视"};
String[]girlfaces = {"美奂绝伦","亭亭玉立","闭月羞花","婀娜多姿","相貌丑陋","面目可憎","天真可爱"};
public Role() {
}
public Role(String name, int blood ,char gender) {
this.name = name;
this.blood = blood;
this.gender = gender;
setFace(face);
}
public void show(){
System.out.println("姓名 "+this.name);
System.out.println("性别 "+this.gender);
System.out.println("长相 "+this.face);
System.out.println("血量 "+this.blood);
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public String getFace() {
return face;
}
//对于相貌的设置我们采取随机的方式
public void setFace(String face) {
Random r = new Random();
//1.先判断角色的性别,对应随机不同的样貌库
if(this.getGender()=='男'){
int index = r.nextInt(boyfances.length);//得到男角色样貌数组的随机索引
this.face= boyfances[index];
}else if(this.gender=='女'){
int index = r.nextInt(girlfaces.length);
this.face = girlfaces[index];
}else {
this.face="长相普通";
}
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return blood
*/
public int getBlood() {
return blood;
}
/**
* 设置
* @param blood
*/
public void setBlood(int blood) {
this.blood = blood;
}
//人物攻击行为
//方法的调用对象攻击参数对象
public void attack(Role role){
//this表示方法调用者
//用随机数表示造成的伤害
Random r = new Random();
int hurt = r.nextInt(20) + 1;
int remainBlood = role.getBlood()-hurt;
//保证其血量不会出现负数的异常情况
remainBlood = role.getBlood() - hurt <= 0 ? 0 : remainBlood;
role.setBlood(remainBlood);
System.out.println(this.name+"用拳头打了"+role.getName()+"一下, " +
"造成"+hurt+"点的伤害,"+role.getName()+"还剩下"+role.getBlood()+"点血量");
}
}
对于角色攻击的优化,和前面相似,可以采取随机效果,也可以根据描述的程度,可以用if判断
对象数组练习
- 练习1
- 测试类
package Test;
import com.an.a.Goods;
public class GoodsTest {
public static void main(String[] args) {
Goods [] arr = new Goods[3];
Goods g1 = new Goods("123","华为p20",3456,100);
Goods g2 = new Goods("001","小米手环",600,190);
Goods g3= new Goods("007","苹果",2.4,200);
arr[0]=g1;
arr[1]=g2;
arr[2]=g3;
for (Goods goods : arr) {
System.out.println("id为 "+goods.getId());
System.out.println("商品名称为 "+goods.getName());
System.out.println("商品价格为 "+goods.getPrice());
System.out.println("商品库存为 "+goods.getCount());
}
}
}
对于商品类为简单的javaBean类,这里不再展示
键盘录入
主要区分next()和nextXXX的区别
nextxxx遇到空格 回车 制表符 就会停止录入
nextLine可以接受空格 制表符 遇到回车才会停止
nextLine和nextXXX是两套键盘录入体系,建议两者不要混用
练习2
测试类
package com.an.a;
import java.util.Scanner;
public class CarTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Car[] cars = new Car[3];
for(int i=0;i<3;i++){
System.out.printf("请输入第%d个车的信息:\n",i+1);
System.out.println("请输入车的品牌:");
String brand = sc.next();
System.out.println("请输入车的价格:");
double price = sc.nextDouble();
System.out.println("请输入车的颜色:");
String color= sc.next();
cars[i]=new Car(brand,price,color);
}
for (Car car : cars) {
System.out.println("车的品牌为:"+car.getBrand());
System.out.println("车的价格为:"+car.getPrice());
System.out.println("车的颜色为:"+car.getColor());
}
}
}
car类是简单的javaBean类
练习3--计算出收集的平均价格
测试类
package com.an.a;
public class PhoneTest {
public static void main(String[] args) {
Phone [] arr = new Phone[3];
Phone p1 = new Phone("华为",2333434,"red");
Phone p2 = new Phone("小米",2322222,"green");
Phone p3 = new Phone("魅族",2100000,"yellow");
arr[0]=p1;
arr[1]=p2;
arr[2]=p3;
//计算平均价格
int sum=0;
for (int i = 0; i < arr.length; i++) {
int price = arr[i].getPrice();
sum+=price;
}
System.out.println("平均价格为:"+sum/3);//平均价格为:2251885
}
}
练习4
测试类
package com.an.a;
public class GirlFrendsTest {
public static void main(String[] args) {
GirlFrends[] arr = new GirlFrends[4];
GirlFrends g1 = new GirlFrends("小淡淡", 23, '女', "跳舞");
GirlFrends g2 = new GirlFrends("小红红", 22, '女', "画画");
GirlFrends g3 = new GirlFrends("小彤彤", 18, '女', "游泳");
GirlFrends g4 = new GirlFrends("小哈哈哈", 21, '女', "下棋");
arr[0] = g1;
arr[1] = g2;
arr[2] = g3;
arr[3] = g4;
//计算平均年龄
int sum = 0;
int avg = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i].getAge();
if (i == arr.length - 1) {
avg = sum / arr.length;
}
}
System.out.println("平均年龄为:"+avg);
int count=0;//储存年龄比平均值低的数量
for (int i = 0; i < arr.length; i++) {
if(arr[i].getAge()<avg){
count++;
System.out.println("姓名:"+arr[i].getName());
System.out.println("年龄:"+arr[i].getAge());
System.out.println("性别:"+arr[i].getSex());
System.out.println("爱好:"+arr[i].getHobby());
}
}
System.out.println("年龄比平均年龄低的女朋友数量为 :"+count);
}
}
女朋友类为简单的javaBean类,这里不再写出
练习5(该题的逻辑较复杂,可作为小项目)
思路:添加一个元素,创建一个长度比原数组长度+1的数组,然后将原数组的数据拷贝到新数组中
-
主题思想
-
删除
判断学号是否已经存在
删除的话,将这样对象的索引设置成null就行了,在遍历的时候通过是否为Null决定是否遍历
- 查询操作