继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

2-Java面向对象-封装

幕布斯6054654
关注TA
已关注
手记 1264
粉丝 219
获赞 1011

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

封装:

将类的某些信息隐藏在类内部, 不允许外部程序直接访问;通过该类提供的方法来实现对隐藏信息的操作和访问;

隐藏对象的信息 同时 留出访问的接口

生活中的案例:

ATM机,我们可以通过它存取款、转账、余额查询操作。钞票是ATM内的重要信息,但我们在外部是无法直接看到的,这就是ATM机对于钞票这个重要信息的隐藏。但是ATM拥有操作屏, 插卡口,取钞口等,用户通过简单的操作就可以实现隐藏钞票的操作。

特点:

  1. 只能通过规定的方法访问数据

  2. 隐藏类的实例细节,方便修改和实现

封装的代码实现(上)

private 加在属性上,表明这个属性只能在当前类内被访问。

实现步骤: 修改属性的可见性,设为private; 创建getter/setter方法,设为public,用于属性的读写;在getter/setter方法中加入属性控制语句(对属性值的合法性进行判断:性别只能是男和女啊,年龄只能是正值啊)

宠物猫的年龄应该是正数。

  1. 修改属性的可见性

    private String name;    private int age;    private float weight;    private String species;

private表示这个属性只能在Cat类内部进行访问。

5c137d9f0001c56603740061.jpg

可以看到此时这些属性已经无法再类外直接通过对象进行访问了。

访问修饰符: private public

  1. 还有什么呢?

  2. 访问权限是怎样的?

  3. 设置公有的getter/setter方法隐藏; 在get/set方法中添加对属性的限定。

public String getName() {        return name;
    }public void setName(String name) {        this.name = name;
    }



可以通过快捷键:

5c137da000010fd902730024.jpg

进行快速的生成。

public String getName() {        return "我是一只名叫"+name+"小猫";
    }

里面可以加入自己的一些逻辑,包装。下面是封装之后的使用:

        Cat oneCat = new Cat();
        oneCat.setAge(10);
        oneCat.setName("花花");
        oneCat.setSpecies("中华田园猫");
        oneCat.setWeight(1000);

        System.out.println("年龄: "+ oneCat.getAge());
        System.out.println("昵称: "+ oneCat.getName());
        System.out.println("体重: " + oneCat.getWeight());
        System.out.println("品种: " + oneCat.getSpecies());

运行结果:

5c137da00001aa6703610139.jpg

封装代码实现下

注意只有getXXX方法的属性是只读属性;只有setXXX方法的属性是只写属性。下面我们在set方法中加入一些验证

    public void setAge(int age) {        if (age <0){
            System.out.println("猫的年龄必须大于0");
        }else{            this.age = age;
        }
    }  
  // 调用
  oneCat.setAge(-1);

5c137da00001d10b01810047.jpg

可以通过异常处理优化程序,后面会详细介绍。如果在构造函数中不使用get set 而是直接赋值,可以正常运行,但是不推荐。因为写在get/set里的验证逻辑将不会被执行。

public Cat(int age){  this.age = age;
}

Cat oneCat = new Cat(-1);
System.out.println("年龄: "+ oneCat.getAge());

5c137da00001fd0300960025.jpg

因此推荐在构造方法中也同样使用get/set

编程练习

编写自定义类实现图书信息设置,运行参考效果如下所示:

5c137da10001630503150230.jpg

属性: 书名、作者、出版社、价格
方法: 信息介绍

package cn.mtianyan.book;public class Book {    public String getTitle() {        return title;
    }    public void setTitle(String title) {        this.title = title;
    }    public String getAuthor() {        return author;
    }    public void setAuthor(String author) {        this.author = author;
    }    public String getPulishingHouse() {        return pulishingHouse;
    }    public void setPulishingHouse(String pulishingHouse) {        this.pulishingHouse = pulishingHouse;
    }    public float getPrice() {        return price;
    }    public void setPrice(float price) {        if(price < 10){
            System.out.println("图书价格最低10元");            this.price =10;
        }else{            this.price = price;
        }
    }    private String title;    private String author;    private String pulishingHouse;    private float price;    public Book(String title,String author,String pulishingHouse,float price){        this.setTitle(title);        this.setAuthor(author);        this.setPulishingHouse(pulishingHouse);        this.setPrice(price);
    }    public void info(){
        System.out.println("书名: " + this.getTitle());
        System.out.println("作者: " + this.getAuthor());
        System.out.println("出版社: " + this.getPulishingHouse());
        System.out.println("价格: " + this.getPrice());
    }
}
package cn.mtianyan.book;public class BookTest {    public static void main(String[] args) {
        Book one = new Book("红楼梦","曹雪芹","人民文学出版社",6);
        Book two = new Book("小李飞刀","古龙","中国长安出版社",55.5f);
        one.info();
        System.out.println("===================");
        two.info();
    }
}

5c137da10001e8d803510271.jpg

使用包进行类管理

文件夹进行文件管理,同一个文件中可以存放多个不同的文件,同名的文件只能存放在不同的文件夹中。

在Java中如何进行不同类文件的管理呢:java中我们通过包来管理java文件,解决同名文件冲突。

Java中一个包里不能存在同名类

5c137da10001132f07030163.jpg

域名倒序+模块+功能(域名全部小写)

package cn.mtianyan.book;

包的定义必须放在Java源文件中的第一行,定义类时,我们应该遵循单一职责原则,因此在建立包的时候,建议每个包内存储信息功能单一。

如何实现跨包的类调用?有几种调用形式?我如何告诉编译器我要调用的是哪个包里的Cat呢?

import cn.mtianyan.animal.*; // 加载包下的所有类import cn.mtianyan.animal.cat; // 加载指定包下的指定类

建议采用 import包名.类名 的方式加载,提高效率

可以直接在程序代码中加载cn.mtianyan.animal.cat

 cn.mtianyan.animal.Cat cat = new cn.mtianyan.animal.Cat();

加载类的顺序跟import导入语句的位置无关,具体包的指定,优先级大于通配符。

import cn.mtianyan.*

import包名.* 只能访问指定包名下的类,无法访问子包下的类

包的作用:

  1. 管理Java文件

  2. 解决同名文件冲突

定义包:

语法: package 包名;例: package cn.mtianyan.animal;

注意: 必须放在Java源文件中的第一行;-个Java源文件中只能有-个package语句;包名全部英文小写;命名方式:域名倒序+模块+功能

导入包语法:

import 包名.类名;

例:导入包中全部类: import cn.mtianyan.*;导入包中指定类: import cn.mtianyan.animal.Cat;

tips(常用系统包):

包名内容
java.lang包含Java语言基础的类,该包系统加载时默认导入 如:System、String、Math
java.util包含Java语言中常用工具 如: Scanner、Random
java.io包含输入、输出相关功能的类 如: File、InputStream

编程练习

编写自定义类实现用户信息类.

程序参考运行效果图如下:

5c137da200015e4402000216.jpg

任务

用户类: 属性(用户名、密码)
用户管理类: 方法(用户信息验证)

package cn.mtianyan.user;public class User {    private String username;    public User(String username, String password) {        this.setUsername(username);        this.setPassword(password);
    }    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;
    }    private String password;
}
package cn.mtianyan.user;public class UserManage {    public String checkUser(User one,User two){
        System.out.println("用户名: "+one.getUsername());
        System.out.println("密码: "+one.getPassword());
        System.out.println("用户名: "+two.getUsername());
        System.out.println("密码: "+two.getPassword());
        System.out.println("=================");        if (one.getUsername().equals(two.getUsername())){            return  "用户名一致";
        }else {            return  "用户名不一致";
        }
    }
}
package cn.mtianyan.user;public class Test {    public static void main(String[] args) {
        User one = new User("Lucy","123456");
        User two = new User("Mike","123456");
        UserManage userManage = new UserManage();
        System.out.println(userManage.checkUser(one,two));
    }
}

运行结果:

5c137da200017fd103580193.jpg

Static关键字(上)

20180801175056_cZuD35_Screenshot.jpeg

static表示静态信息,它在Java程序中可以和喞些信息組合使用?用它修饰的信息具有哪些特征呢?

public float price; //cat类中
Cat one = new Cat();
one.price = 2000;

Cat two = new Cat();
two.price = 150;

上述代码的结果显然脑补都可以脑补到.但假如我们为价格添上static修饰

public static int price; //售价

20180801175644_iFjEHz_Screenshot.jpeg

添加了static修饰之后,price变成了斜体。

20180801175837_ddMw5l_Screenshot.jpeg

可以看到在main中取值时,提示我们静态的成员变量,应该以一种静态的访问方式访问。此时的运行结果中,两只猫的价格都变成了150。

Static表示的是一个静态的,修饰成员时叫做一个静态成员或类成员,它是属于这个类所有的。无论这个类实例化出多少的对象,它都会共用同一块内存空间。

20180801180156_R60V5c_Screenshot.jpeg

后赋值的会将前面的内存中的内容覆盖掉; 类对象共享;类加载时产生,销毁时释放,生命周期长

one.price = 2000;
Cat.price = 3000;

既可以通过对象名,也可以通过类名来访问。

Static关键字中

Static 加在属性前面,被称为静态属性,类属性。同理,Static添加到方法前面就从普通方法,变成了类方法。

public static void eat(){
        System.out.println("小猫吃鱼");
}

类方法的调用和我们的静态成员变量的访问时一样的,既可以通过类,也可以通过对象。

        oneCat.eat();
        Cat.eat();

推荐调用方式:类名.静态成员

除了加在属性,方法,static还可以加在哪些地方呢?

20180801181018_EWrNSO_Screenshot.jpeg



作者:天涯明月笙
链接:https://www.jianshu.com/p/07e3037a3411


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP