封装的概念和特点

封装

1.将类的某些信息隐藏在类内部,不允许外部程序直接访问。
2.通过该类提供的方法来实现对隐藏信息的操作和访问。
3.隐藏对象的信息。
4.留出访问的接口

特点:

1.只能通过规定的方法访问数据;
2.隐藏类的实例细节,方便修改和实现;

封装的代码实现(上)

封装的代码实现实现步骤:
1.修改属性的可见性设为private(限定只能在当前类中被访问)
2.创建getter/setter方法,设为public用于属性的读写
3.在getter/setter方法中加入属性控制语句;

例子:

package com.imooc.animal;
/**

- 宠物猫类
- @author HeFeihong
  *
  */

public class Cat {
    //成员属性:昵称、年龄、体重、品种
    //修改属性的可见性---private限定只能在当前类内访问
    private String name;//昵称
    int month;//年龄
    double weight;//体重
    String species;//品种
    
public Cat() {
    
}

public Cat(String name) {
    System.out.println("我是带参构造方法");
}

public Cat(String newName,int newMonth,double newWeight,String newSpecies) {
    name=newName;
    month=newMonth;
    weight=newWeight;
    species=newSpecies;
}
//创建get/set方法
//在get/set方法中添加对属性的限定
public void setName(String name) {
    this.name=name;
}
public String getName() {
    return  "我是一只名叫:"+this.name+"的宠物猫";
}

}
package com.imooc.animal;

public class CatTest {
    public static void main(String[] args) {
        //对象实例化
        Cat one=new Cat("花花",2,1000,"英国短毛猫");
        //测试
        one.setName("凡凡");
        System.out.println(one.getName());
    }
}

封装的代码实现(下)

属性只有setXXX方法--只读属性
属性只有getXXX方法--只写属性

package com.imooc.animal;
/**

- 宠物猫类
- @author HeFeihong
  *
   */

public class Cat {
    //成员属性:昵称、年龄、体重、品种
    //修改属性的可见性---private限定只能在当前类内访问
    private String name;//昵称
    private int month;//年龄
    private double weight;//体重
    private String species;//品种
    
public Cat() {
    
}

public Cat(String name) {
    System.out.println("我是带参构造方法");
}

public Cat(String newName,int newMonth,double newWeight,String newSpecies) {
    name=newName;
    month=newMonth;
    weight=newWeight;
    species=newSpecies;
}
//创建get/set方法
//在get/set方法中添加对属性的限定
public void setName(String name) {
    this.name=name;      //最好改为this.setName=name;
}
public String getName() {
    return  "我是一只名叫:"+this.name+"的宠物猫";
}

​    
public int getMonth() {
    return month;
}

public void setMonth(int month) {
    if(month<=0) {
        System.out.println("输入信息错误,宠物猫的年龄必须大于0");
    }else
        this.month = month;
}

public double getWeight() {
    return weight;
}

public void setWeight(double weight) {
    this.weight = weight;
}

public String getSpecies() {
    return species;
}

public void setSpecies(String species) {
    this.species = species;
}

}
package com.imooc.animal;

public class CatTest {
    public static void main(String[] args) {
        //对象实例化
        Cat one=new Cat("花花",2,1000,"英国短毛猫");
        //测试

​        one.setName("凡凡");
​        one.setMonth(-3);//=-3
​        System.out.println(one.getName());
​        System.out.println(one.getMonth());
​    }
}

编程练习

编写自定义类实现图书信息设置。请按照编辑器中的注释,在对应的空白区域填写对应的代码,完成程序设计。

运行参考效果如下所示:

输入信息错误,图书价格必须大于10
书名:红楼梦
作者:曹雪芹
出版社:人民文学出版社
价格:10.0元
==================================
书名:小李飞刀
作者:古龙
出版社:中国长安出版社
价格:55.5元

任务

属性:书名、作者、出版社、价格

方法:信息介绍

要求:

1、 设计构造函数实现对属性赋值

2、 设置私有属性,get/set方法实现对属性的访问

3、 限定图书价格必须大于10,如果无效需进行提示,并强制赋值为10

4、 限定作者、书名均为只读属性

5、信息介绍方法描述图书所有信息

public class Book {
  //私有属性:书名、作者、出版社、价格
  private String name;
  private String author;
  private String press;
  private double price;
     
  //通过构造方法实现属性赋值
  public Book(){
      
  }
  public Book(String name,String author,String press,double price){
      this.name=name;
      this.author=author;
      this.press=press;
      this.price=price;
  }

/*通过公有的get/set方法实现属性的访问,其中:
1、限定图书价格必须大于10,如果无效需进行提示,并强制赋值为10
2、限定作者、书名均为只读属性
*/

  //信息介绍方法,描述图书所有信息
  public String getName() {
      return  "书名:"+this.name;
  }
  public String getAuthor(){
      return "作者:"+this.author;
  }
  public void setPress(String press){
      this.press=press;
  }
  public String getPress(){
      return "出版社:"+this.press;
  }
  public void setPrice(double price){
      if(price<10){
          System.out.println("输入信息错误,图书价格必须大于10");
          this.price=10;
      }else
          this.price=price;
  }
  public double getPrice(){
      return this.price;
  }

}
public class BookTest {

 // 测试方法
 public static void main(String[] args) {
  //实例化对象,调用相关方法实现运行效果
  Book one=new Book("红楼梦","曹雪芹","人民文学出版社",15);
  one.setPrice(5);
  System.out.println(one.getName());
  System.out.println(one.getAuthor());
  System.out.println(one.getPress());
  System.out.println("价格:"+one.getPrice()+"元");
  System.out.println("==================================");
  
  Book two=new Book("小李飞刀","古龙","中国长安出版社",55.5);
  System.out.println(two.getName());
  System.out.println(two.getAuthor());
  System.out.println(two.getPress());
  System.out.println("价格:"+two.getPrice()+"元");
 }

}

使用包进行类管理--创建包

包:
一个包内,类不能重名
域名的倒叙+模块+功能
域名全都小写
每个包存储信息功能单一

使用包进行类管理--导入包

如果要导入的多个包中有相同的类名,如:

import com.imooc.animal.Cat;
import com.imooc.mechanics.Cat;

第二条语句系统会报错,系统分不清要导入哪个Cat。
再比如:

import com.imooc.mechanics.*;
import com.imooc.animal.Cat;

这样系统调用Cat类时,会解析animal下的类,而不会找到mechanics下的Cat类。因为animal下的Cat类首先解析。如果要访问mechanics下的Cat类时,只能在代码中直接加载。
import加载时,如有 import com.imooc.*;只能加载imooc文件夹下能找到的类,而不会再向下级文件查找。没有类的话就找不到。

//import com.imooc.animal.*;//加载com.imooc.animal下所有类

import com.imooc.animal.Cat;//加载com.imooc.animal下指定的cat类

//直接加载com.imooc.animal.catTest

com.imooc.animal.CatTest tex=new com.imooc.animal.CatTest();

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

编程练习2

编写自定义类实现用户信息类。请按照编辑器中的注释,在对应的空白区域填写对应的代码,完成程序设计。

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

用户名Lucy
密码:123456
用户名Mike
密码:123456
========================
用户名不一致
密码一致

任务

  • 用户类:

​ 属性:用户名、密码

  • 用户管理类:

​ 方法:用户信息验证

要求:

​ 1、 设计构造函数实现对属性赋值

​ 2、 设置私有属性,get/set方法实现对属性的访问

​ 3、用户信息验证判断两个用户信息是否一致

PS: 可以通过equals()方法进行字符串内容的判断,如果内容相等返回值为true,反之为false,如当str代表用户性别时,可以通过如下代码,判断性别为“男”还是“女”

public class UserManager{
    // 用户信息验证的方法
    public String checkUser(User one, User two) {
       // 判断用户名是否为空,是否一致
/*       if(one.getUsername().equals(null)){
           System.out.println("用户名为空");
       }
       else*/ if(one.getUsername().equals(two.getUsername())){
           System.out.println("用户名一致");
       }
       else{
           System.out.println("用户名不一致");
       }
          
// 判断密码是否为空,是否一致

/*      if(one.getPassword().equals("")){
          System.out.println("密码为空");
      }
      else*/ if(one.getPassword().equals(two.getPassword())){
          System.out.println("密码一致");
      }
 
return "" ;  

}

}  
public class User{
    //定义属性用户名、密码
    private String username;
    private String password;
    
public User(){
    
}
public User(String username,String password){
    
}

public void setUsername(String username){
    this.username=username;
}
public String getUsername(){
    return this.username;
}

public void setPassword(String password){
    this.password=password;
}
public String getPassword(){
    return this.password;
}

public void message(){
    System.out.println("用户名"+username);
    System.out.println("密码:"+password);
}

}
public class Test{
    // 测试方法
    public static void main(String[] args) {
     //实例化对象,调用相关方法实现运行效果
     User one=new User();
     User two=new User();
     one.setUsername("Lucy");
     one.setPassword("123456");
     two.setUsername("Mike");
     two.setPassword("123456");
     UserManager test=new UserManager();
     one.message();
     two.message();
     System.out.println("========================");
     System.out.println(test.checkUser(one,two));
    }
}

static关键字

static:静态成员、类成员
特征:类加载时就产生,无论创建多少个对象,它们共用同一块静态空间,只有当所有对象被销毁时,static开辟的静态空间才会被销毁。static定义的变量以最后赋值为基准,
静态成员的访问方法:
1:对象.成员
2:类.成员

static(静态,静态成员,类成员): 可以添加到成员属性或成员方法前面
1.添加到成员属性前面→成员属性变为静态属性(类属性)→类属性的调用(对象名或类名)
2.添加到普通成员方法前面→成员方法变成类方法→类方法的调用(同上,通过对象名或类名)
3.添加到类前面是非法的
4.在方法中可定义局部变量,在局部变量前面不可以添加static修饰符,只能加final
5.在我们前面定义的成员方法当中,我们可以直接调用当前类当中的任意成员,比如在普通成员方法run()中,既可以直接调用与它同一类的静态方法eat(),也可以通过this关键字调用普通成员属性或静态属性。也就是说,在成员方法中,可以直接访问类的静态成员
6.但是静态方法当中不能直接访问非静态成员(包括非静态的方法和属性),只能直接调用静态成员
7.static和this关键字也是冲突的,static代表类共享,而this代表实例,因此在静态方法中不可以使用this关键字


{}代码块 (知识点梳理)
1.(1)当它出现在方法里的时候,我们称之为普通代码块,它的执行顺序和一般语句的执行顺序是一样的,即顺序执行。
(2)它可以有任意数量,在方法中有任意位置。
2.(1)当它在不在方法中,而在类里单独出现时,被称为构造代码块,在创建对象时即被调用,优先于构造方法执行。
(2)在类中同样能有多个。
(3)在构造代码块前面加static之后,它就升级成了静态代码块,静态代码块首先执行,在类中能有多个静态代码块。
3.问:静态代码块代表的是类共有的相关信息,当我们在测试类中创建了多个对象实例的时候,静态代码块会执行几次,而构造代码块又会执行几次呢?
答:静态代码块,无论实例化多少个对象,它只会被执行一次,而且是最先被全部执行完毕;而构造代码块,每次进行实例化的时候,它都会被执行一次
4.在静态代码块中,只能给静态成员进行赋值,不能给普通成员赋值;在构造代码块中就没这些限制咯

编程练习3

请根据效果图以及任务要求完成代码。

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

CodeBlock的静态代码块
CodeBlock的主方法
产生Code类实例对象
Code静态代码块
Code构造代码块
Code构造方法
产生CodeBlock类实例对象
CodeBlock的构造代码块
CodeBlock构造方法

任务

  1. 创建类Code,类中编写构造块、静态代码块以及构造方法
  2. 创建CodeBlock,类中编写的构造块、静态代码块以及构造方法
  3. 在主函数中测试他们的执行的优先顺序(运行结果参见效果图)
class Code{
   //创建外部类Code构造块(构造块)
   {
       System.out.println("Code构造代码块");
   }

   //创建外部类Code静态代码块(静态代码块)
   static{
       System.out.println("Code静态代码块");
   }

   //创建外部类Code构造方法(构造方法)
   public Code(){
       System.out.println("Code构造方法");
   }

} 
public class CodeBlock{
   // 创建CodeBlock的构造块
   {
       System.out.println("CodeBlock的构造代码块");
   }

   //创建CodeBlock的静态代码块
   static{
       System.out.println("CodeBlock的静态代码块");
   }

   //创建CodeBlock的构造方法
   public CodeBlock(){
       System.out.println("CodeBlock构造方法");
   }



   public static void main(String[] args){
      //编写代码测试运行优先顺序,运行结果参见效果图
      System.out.println("CodeBlock的主方法");
      System.out.println("产生Code类实例对象");
      Code code=new Code();
      System.out.println("产生CodeBlock类实例对象");
      CodeBlock codeblock=new CodeBlock();
      
      
         
   }
}

static关键字(续)

代码块内部的变量存活周期是从代码块开始到代码块结束,作用范围只在代码块内有效,结束之后会被回收。
而方法体的局部变量的作用范围,从定义的位置直到方法体完,且不会回收。

方法体中局部变量的作用域:
1、代码块内部:只在该代码块内生效;
2、代码块外部:从变量被定义开始生效一直到方法结束。

最后修改:2019 年 12 月 31 日 11 : 23 PM
如果觉得我的文章对你有用,请随意赞赏