面向对象基础
面向对象三大基本特征:封装,继承,多态
image.png
设计对象并使用
设计类,创建对象并使用
-
类:是对象共同特征的描述
-
对象:是真实存在的具体实例
-
定义类:
public class 类名{ 1.成员变量(代表属性,一般是名词) 2.成员方法(代表行为,一般是动词) 3.构造器 4.代码块 5.内部类 }
-
定义对象
类名 对象名 = new 类名();
-
使用对象
- 访问属性:对象名.成员变量
- 访问行为:对象名.方法名(……)
定义类的几个补充注意事项
-
成员变量的完整定义格式:
访问级修饰符 数据类型 变量名称 = 初始化值; // 一般无需指定初始化值,存在默认值
-
对象的成员变量的默认值规则
数据类型 明细 默认值 基本类型 byte,short,char,int,long 0 float,double 0.0 boolean false 引用类型 类,接口,数组,String null -
类名的首字母大写,命名有意义,并且满足“驼峰模式”
-
一个Java文件中可以定义多个class类,且只能一个类是public修饰,而且public修饰的类名必须成为代码文件名
实际开发中还是建议一个文件编写一个class类
对象内存图
-
两个对象的内存图:
image.png
在首次加载成员变量和成员方法的时候,成员变量是以默认值的状态存在堆内存,成员方法则以引用地址的形式存放
对象存放在堆内存中
Car c = new Car(); 变量c存储的是对象在堆内存中的地址,其为引用类型
成员变量的数据存放在对象中,而对象又存放于堆内存中
-
两个变量指向同一个对象的内存图(如下:将学生类型的变量s1赋值给学生类型的s2)
image.png
垃圾回收
- 当堆内存中的类对象或数组对象,没有被任何变量引用(指向)时,就会被判定为内存中的“垃圾”
- Java存在自动垃圾回收器,会定期清理垃圾
构造器
对象是通过构造器得到的
-
构造器的作用:用于初始化一个类的对象,并返回对象的地址
-
构造器的定义格式
修饰符 类名(形参列表){ …… }
-
构造器的分类
- 无参构造器(默认存在的):初始化对象时,成员变量的数据均采用默认值
- 有参构造器:在初始化对象的时候,同时可以为对象进行赋值
public class Car(){ …… //无参数构造器 public Car(){ …… } //有参构造器 public Car(String a, String b){ …… } }
-
初始化对象的格式:
类型 变量名称 = new 构造器();
Car c= new Car();
-
注意事项:
- 任何类被定义出来,默认就带了无参构造器,写不写都有
- 一旦定义了有参构造器,无参构造器就没有了,此时必须自己写一个同名的无参构造器
this关键字
-
作用:出现在成员方法中&构造器中,代表当前对象的地址,用于访问当前对象的成员变量,成员方法
-
this出现在有参构造器中的用法:
image.png
-
this出现在成员方法中的用法:
image.png
封装
-
定义:隐藏实现细节,暴露出合适的访问方式。(合理隐藏,合理暴露)
-
实现步骤:
-
一般对成员变量使用private(私有)关键字修饰进行隐藏,private修饰后该成员变量就只能在当前类中访问
-
提供public修饰的公开getter(),setter()方法暴露其取值和赋值
image.png
-
-
封装的好处:
- 加强了程序的安全性
- 适当的封装可以提升开发效率,同时让程序易于维护
标准JavaBean
- 可以理解成为实体类,其对象可以用于在程序中封装数据
- 标准JavaBean需要满足的条件:
- 成员变量使用private修饰
- 为每一个成员变量书写对应的setXxx()/getXxx()方法
- 必须提供一个无参构造器
成员变量&局部变量的区别
区别 | 成员变量 | 局部变量 |
---|---|---|
类中位置不同 | 类中,方法外 | 常见于方法之中 |
初始化值不同 | 有默认初始化值 | 没有默认值,使用之前必须初始化 |
内存位置不同 | 堆内存(因为成员变量属于对象) | 栈内存 |
生命周期不同 | 随着对象的创建而存在,随着对象的消失而消失 | 随着方法的调用而存在,随着方法的运行结束而消失 |
作用域 | 在所属的大括号中 |
面向对象综合案例(JavaBean)
购物车
-
ShoppingCart
package com.java.test; import java.util.Scanner; /** * 面向对象编程训练,购物车模块模拟 */ public class ShoppingCart { public static void main(String[] args) { //1.定义商品类,用于后期创建商品对象 //2.定义购物车对象,使用一个数组对象表示 Goods[] shopCart = new Goods[100]; //装商品对象,因此类型就是Goods //3.搭建操作架构 MENU: while (true) { System.out.println(); System.out.println("请输入如下命令进行操作"); System.out.println("添加商品到购物车:add"); System.out.println("查询商品到购物车:query"); System.out.println("修改商品购买数量:update"); System.out.println("结算总金额并付款:pay"); Scanner sc = new Scanner(System.in); System.out.println("请您输入命令:"); String cmd = sc.next(); switch (cmd) { case "add": addGoods(shopCart, sc); break; case "query": queryGoods(shopCart); break; case "update": updateGoods(shopCart, sc); break; case "pay": pay(shopCart); break; default: System.out.println("查无此功能!"); } if (cmd.equals("pay")) { break MENU; } } } /** * 所有功能均未开发输入纠错机制,测试数据请合法输入 */ private static void pay(Goods[] shopCart) { queryGoods(shopCart); double money = 0; for (int i = 0; i < shopCart.length; i++) { Goods g = shopCart[i]; if (g != null) { money += (g.getPrice() + g.getBuyNumber()); } else { break; } } System.out.println("订单总金额:" + money + "\t\t单位:元"); } private static void updateGoods(Goods[] shopCart, Scanner sc) { while (true) { //让用户输入要修改购买数量的商品的id进行操作 System.out.println("请您输入您要修改的商品的id:"); int id = sc.nextInt(); Goods g = getGoodsById(id, shopCart); if (g == null) { //没有该商品 System.out.println("您的购物车不存在商品拥有此id,请重新输入"); } else { //存在该商品对象,下一步进行修改 System.out.println("请您输入商品" + g.getName() + "的最新购买数量:"); int buyNumber = sc.nextInt(); g.setBuyNumber(buyNumber); System.out.println("修改完成!"); queryGoods(shopCart); break; } } } public static Goods getGoodsById(int id, Goods[] shopCart) { for (int i = 0; i < shopCart.length; i++) { Goods g = shopCart[i]; if (g != null) { //判断所得id是否为目标id if (g.getId() == id) { return g; } } else { return null; //找完了全部存在的商品都没有找到目标id } } return null; //找完了100(数组的长度)个商品都没有找到目标id } private static void queryGoods(Goods[] shopCart) { System.out.println("+======================查询购物车信息如下======================"); System.out.println("编号\t\t\t名称\t\t\t\t\t\t\t价格\t\t\t购买数量"); for (int i = 0; i < shopCart.length; i++) { Goods g = shopCart[i]; if (g != null) {// 展示这个商品对象 System.out.println(g.getId() + "\t\t\t" + g.getName() + "\t\t\t\t\t\t\t" + g.getPrice() + "\t\t\t" + g.getBuyNumber()); } else {// 遍历结束 break; } } System.out.println("==========================================================="); } private static void addGoods(Goods[] shopCart, Scanner sc) { // 可以将扫描器当作参数传进方法,方法内部就不用再额外建立扫描器 System.out.println("请您输入购买商品的编号(不重复):"); int id = sc.nextInt(); System.out.println("请您输入购买商品的名称:"); String name = sc.next(); System.out.println("请您输入购买商品的数量:"); int buyNumber = sc.nextInt(); System.out.println("请您输入购买商品的价格:"); double price = sc.nextDouble(); // 将购买的商品的信息封装成一个商品对象 Goods g = new Goods(); g.setId(id); g.setName(name); g.setBuyNumber(buyNumber); g.setPrice(price); // 把商品对象添加到购物车数组 for (int i = 0; i < shopCart.length; i++) { if (shopCart[i] == null) { // 说明此位置没有元素存入,把我们新买的商品添加到此处即可 shopCart[i] = g; //存放的是地址 break; //结束,因为商品已经存入,不需要再寻找位置了 } System.out.println("添加商品:" + g.getName() + "添加到购物车完成"); } } }
-
Goods
package com.java.test; public class Goods { private int id; private String name; private double price; private int buyNumber; public Goods() { } public Goods(int id, String name, double price, int buyNumber) { this.id = id; this.name = name; this.price = price; this.buyNumber = buyNumber; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getBuyNumber() { return buyNumber; } public void setBuyNumber(int buyNumber) { this.buyNumber = buyNumber; } }
网友评论