概述
定义
**拆字分析:**面向:找、拿 ; 对象:东西 ;
那么面向对象编程的意思就是:找或拿东西过来编程。
其实,我们早就已经做到面向对象编程了,只是没有意识到,举个例子:
import java.util.Scanner;
public class OperateDemo {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
System.out.println("Please enter your age.");
int age = sc.nextInt();
System.out.println("Oh,you're "+age);
System.out.println("Please enter your name.");
String name =sc.next();
System.out.println("Welcome "+name);
}
}
在这里,为了实现键盘输入,我们找了Scanner这个包来完成,这就是面向对象编程。
好处
现实生活中,我们要做什么事,都会去找一个个的东西来解决。在编程里,我们也是去找一个个东西来实现我们的目标,那么面向对象编程的好处就在于符合我们人类的思维习惯,使编程更简单、更好理解。
面向对象的编程学什么
设计对象并使用
类与对象
_类:_对象共同特征的描述
**对象:**是真实存在的具体实例
如图,在现实生活中,对象就好比一座建筑、一台手机、一辆车,而类则是它们的设计图。
如何设计类
public class 类名{
1.成员变量(代表属性,一般是名词)
2.成员方法(代表行为,一般是动词)
3.构造器(后面再讲)
4.代码块(后面再讲)
5.内部类(后面再讲)
}
public class Car{
//属性
String name;
Double price;
//行为
public void start(){}
public void run(){}
}
注意,这里并不是public static ,而是单独一个public !
得到类的对象和使用对象
得到类的对象:格式: 类名 对象名 = new 类名()
Car c = new Car();
使用对象:访问属性:对象名.成员变量
访问行为:对象名.方法名(……)
注意事项:
- 一个Java文件中可以定义多个class类,但是只能有一个类是public修饰,并且public修饰的类名必须是代码文件夹名(实际开发最好还是一个代码文件只定义一个类)
- 成员变量的完整定义格式: 修饰符 数据类型 变量名 = 初始化值;(一般来说可以不定义初始化值,存在着默认值)
对象在内存中的运行机制
public class Car {
String name;
double price;
public void start(){
System.out.println(name + "启动了");
}
public void run() {
System.out.println("价格为"+price+"w"+name + "正在行驶!");
}
}
public class Test {
public static void main(String[] args) {
Car c1 = new Car();
c1.name = "奔驰";
c1.price = 39.78;
c1.start();
c1.run();
System.out.println(c1.name);
System.out.println(c1.price);
Car c2 = new Car();
c2.name = "宝马";
c2.price = 32.4;
c2.start();
c2.run();
System.out.println(c2.name);
System.out.println(c2.price);
}
}
以汽车启动代码为例:
1.将Test类加载到方法区,同时将类中的main方法提到栈内存中去。
2.代码开始运行,将Car类加载到方法区,c1变量加载到main方法下,同时在堆内存里存放对象的相关值(此时还只是默认值)和方法,把对象在堆内存的地址赋值给c1。
由于Car类方法的代码可能会很多,会占据堆内存的空间,所以说堆内存里存储的是对象方法的引用地址。
3.代码继续运行,将c1指向对象的值改变,然后,通过c1里的地址值找到对象,再通过方法引用地址找到start方法,加载到栈内存里执行,run方法同理。
4.c2变量的操作同理:
以上是两个变量一一对应各自的对象的情况,但还存在着一种情况:两个变量对应一个对象
将上面代码的第二十行Car c2 = new Car();
更改,其余不变Car c2 = c1;
这样会使c1,c2两个变量中存储的地址一致。此时,对c2指向对象中的值进行更改,c1指向对象中相应的值也会更改,因为它们都指向堆内存的同一个对象。
补充:垃圾回收
当堆内存中的对象,没有被任何变量指向时,会被判定为内存中的“垃圾”,Java中存在自动垃圾回收器,会定期进行清理,减少栈内存的占用。
每日一练:模拟购物车
需求:
- 实现添加商品到购物车
- 查看购物车里的商品
- 能够修改商品购买数量
- 结算商品价格
分析:
1. 购物车中的每个商品是一个对象,需要定义一个商品类
2. 购物车本身也是个对象,可以用数组对象代表他
3. 完成界面架构,让用户选择操作的功能
代码实现:
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
//定义商品类
//定义购物车对象
Goods[] cart = new Goods[100];
//构建架构
while (true) {
System.out.println("======购物车系统======");
System.out.println("添加商品:add");
System.out.println("查询已添加商品:inquire");
System.out.println("修改商品购买数量:change");
System.out.println("结算:pay");
System.out.println("退出:exit");
System.out.print("请您选择命令进行操作:");
Scanner sc = new Scanner(System.in);
String commod = sc.next();
switch (commod){
case "add":
add(cart,sc);
break;
case "inquire":
inquire(cart);
break;
case "change":
change(cart,sc);
break;
case "pay":
pay(cart);
break;
case "exit":
System.exit(0);
default:
System.out.println("您输入的命令有误!");
}
}
}
private static void pay(Goods[] cart) {
double money = 0.0;
for (int i = 0; i < cart.length; i++) {
Goods g = cart[i];
if (g != null) {
money += g.price * g.number;
} else {
break;
}
}
System.out.println("您最终的价格是:"+money);
}
private static void change(Goods[] cart, Scanner sc) {
//查找id
System.out.print("请输入您想修改的商品的编号:");
int id = sc.nextInt();
Goods g = get(cart,id,sc);
if(g == null){
System.out.println("未查询到该商品!");
}else{
System.out.print("请您输入想要修改的数量:");
g.number = sc.nextInt();
System.out.println("修改完成!");
inquire(cart);
}
}
private static Goods get(Goods[] cart, int id, Scanner sc) {
for (int i = 0; i < cart.length; i++) {
Goods g = cart[i];
if (g != null) {
if (g.id == id) {//找到了
return g;
}
} else {
return null;
}
}
return null;
}
private static void inquire(Goods[] cart) {
System.out.println("============购物车信息============");
System.out.println("编号\t\t名称\t\t价格\t\t\t购买数量");
for (int i = 0; i < cart.length; i++) {
Goods g = cart[i];
if(g!=null){
System.out.println(g.id+"\t\t"+g.name+"\t\t\t"+ g.price+"\t\t\t"+ g.number);
}else{
System.out.println("商品展示完毕!");
break;
}
}
}
private static void add(Goods[] cart, Scanner sc) {
//录入信息
System.out.print("请您输入商品编号:");
int id =sc.nextInt();
System.out.print("请您输入商品名称:");
String name = sc.next();
System.out.print("请您输入商品价格:");
double price =sc.nextDouble();
System.out.print("请您输入购买数量:");
int number = sc.nextInt();
//信息传入对象中
Goods g = new Goods();
g.id = id;
g.name = name;
g.number = number;
g.price = price;
//将地址放入购物车数组去
for (int i = 0; i < cart.length; i++) {
if(cart[i] == null) {
cart[i] = g;
break;
}
}
System.out.println("您的商品"+g.name+"已添加!");
}
}
结果:
后话:这个系统还不够完善,购物车数组不应该设置上限,但好像没学到怎么定义动态数组,只好先定义一个上限0.0。