9.面向对象基础之构造器,封装,JavaBean,内存图,this关键字

面向对象基础

面向对象三大基本特征:封装,继承,多态


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

封装

  • 定义:隐藏实现细节,暴露出合适的访问方式。(合理隐藏,合理暴露)

  • 实现步骤:

    1. 一般对成员变量使用private(私有)关键字修饰进行隐藏,private修饰后该成员变量就只能在当前类中访问

    2. 提供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;
        }
    }
    
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容