封装
啥叫封装?
把属性的设置、获取改成一个特定的方法(set、get等)来实现,而不是直接访问,起到一个保护的作用。
public void setName(String name){
this.name = name; //this待指本类,后面讲述细节
}
public String getName(){ //返回属性
return name;
}
封装、多态、继承是面对对象的三大特性。
为啥要封装
- 方便:一个一个属性设置需要既知道这个属性,也要清楚这个属性的类型。每次有一个新的 对象都要手动设置所有参数。而set方法可以一次性设置完所有应该设置的属性、而且 会提示每个位置应该放的参数和对应的参数类型。
- 安全:保证不会修改一些固定值(eg:final 修饰的属性)。外界不能随意访问到类的属性。
例如:
public class User{
final int lucknumber=85;
String name;
int age;
int id;
int score;
String phoneNum;
String adr;
}
class MainClass{
public static void main(String[] args) { //一个一个属性设置太麻烦!
User user1 = new User(); //需要记住有哪些属性名 以及对应的 属性的类型
user1.name="Stefan";
user1.age=27;
user1.id=001;
user1.phoneNum="12345678910";
user1.adr="北京";
user1.lucknumber=41; //不小心修改类内部固定好的值,报错
}
}
改成封装
/**
* 这是一个封装好的用户类
* @Class Name : User
* @
*/
public class User{
private final int luckynumber=85;
private String name;
private int age;
private int id;
private int score;
private String phoneNum;
private String adr;
public SetAll(String name,int age,int id,int score,String phoneNum,String adr){ //直接设置所有属性
this.name=name;
this.age=age;
this.id=id;
this.score=score;
this.phoneNum=phoneNum;
this.adr=adr;
System.out.println("赋值流程结束 !!");
}
/**
* 设置 name 属性
* 属性类型 字符串 String
* @param name 用户名
*/
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
}
class MainClass{
public static void main(String[] args) { //方便简洁
User user1 = new User();
user1.setAll("Stefan",27,001,"12345678910","北京",41);
user1.setName("Eazin");
System.out.println(user1.getName());
}
}
set方法
- 格式
public void set属性名<首字母大写> (属性类型 属性名 <其实随便起一个就行,为了对应方便辨别>){
this.属性名 = 属性名; //this代指本类对象,就是那个对象调用这个函数,就指这个对象。
}
- 示例
public void setName(String name){
this.name=name;
}
*super 这个关键字在子类中代指父类,指代:子类可以调用、继承到父类的方法。
get方法
- 格式
public 属性类型 get属性名<首字母大写> (){
return 属性名; //直接返回属性
}
- 示例
public String getName(){
return name;
}
构造方法
- 特点
- 每个类都有一个隐式的空参数构造方法。
- 构造方法在创建对象时调用。
- 如果显示写任意一个构造方法将覆盖空参数构造方法。
- 可以重载构造方法(写好几个,名字一样,参数个数或类型不同),根据不同参数来调用对应的构造方法。
- 格式:访问修饰符 方法名(与类名同名)(){方法体}
public User(){
}
- 作用
- 可以实现一行代码 创建对象,并给该对象进行属性的初始化。
- 可以将想要在创建对象时执行的代码放到构造方法中实现。
/**
* 这是一个封装好的用户类
* @Class Name : User
* @
*/
public class User{
private final int num=100;
private String name;
private int age;
private int id;
private int score;
private String phoneNum;
private String adr;
/**
*
* @param name 用户名
* @param age 年龄
* @param id ID
* @param score 积分
* @param phoneNum 手机号码
* @param adr 地址
*/
public User(String name,int age,int id,int score,String phoneNum,String adr){
this.name=name;
this.age=age;
this.id=id;
this.score=score;
this.phoneNum=phoneNum;
this.adr=adr;
System.out.println("赋值流程结束 !!");
}
使用一个陌生的类时 应该观察代码的顺序
首先一个类包含:属性、方法、构造方法、静态属性、静态常量、静态方法
顺序:
构造方法 —— 如何创建一个对象
静态方法 —— 可直接调用什么方法,类名直接调用
属性 —— 查看类有什么属性
方法 —— 能实现什么方法
静态属性、常量:一般是一些配置项、数据、固定参数
*static 修饰的属性、方法用类名可以直接调用。
访问修饰符
限制对象、子类的访问范围。
之前的文章里有详细讲述。
注释
单行注释
//
多行注释
/*
* 中间为了整齐也可以在行开头加*,但不是必要
*
*/
提示——文档注释
/**
* 方法作用
* @param 属性名 解释
**/
在用到自己的方法时根据提示可以看到注释文档内容。(elipse可以idea还没尝试过。)
*@表示 在 的意思。
单列模式
什么是单列模式?
一个类有且仅有一个对象。
实现方式
- 对构造方法私有化——用private修饰构造方法。
- 在类内部创建一个个类的d对象(调用构造函数创造的)。
- 提供一个返回对象的封装出口。
代码示例
public class Chairman {
private String name;
private static Chairman chairman01 = new Chairman("Q"); //类内部设置唯一对象,是静态
public static King getChairman(){ //返回对象方法要设置为静态,意味着可以通过类名直接调用该方法
return chairman01;
}
private King(String name){ //私有构造方法意味着类外不可以创建对象
this.name=name;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
}
public class mainshow(){
public static void main(String[] args){
Chairman c = Chairman.getChairman();
c.setName("W");
System.out.println(c.getName());
}
}
类似于一个单列模式的模式
特点
一个对象可以有多个类,但是类的开发者在内部提供设置好的对象,用户直接获取不用生成。
为什么要这种模式?
有些类的对象创建很复杂 或者使用到一些硬件资源 —— 例如加载驱动等等,而这个流程要求严格,这些使得开发者自己提供创造好的对象十分有必要。
实现方式
- 将构造方法私有化。
- 设置一个创造类的出口方法,返回值类型为本类。
- 在这个方法里创建一个对象(调用构造方法)。
- 对这个对象进行一些复杂操作。
- 返回这个对象。
代码示例
public static Chairman createNewObject(String name){
Chairman obj = new Chairman("Chairman obj");
// 复杂的一些操作
return obj;
}
public class showmain(){
public static void main(){
Chairman c = Chairman.creatNewObject("Q"); //获取设置好的对象
}
}
练习
//院长类——————单列模式,封装好设置属性
public class MyDean {
private String name;
private int age;
private int time_on;
private String pg_type;
private String channel;
private String instituteName;
private static MyDean yz01 = new MyDean("wang",30,31200,"大型益智成长竞技秀","mangoTV","名侦探学院"); //类内部定义唯一对象
private MyDean(String name,int age,int time_on,String pg_type,String channel,String instituteName){ //私有构造方法
this.name = name;
this.age = age;
this.time_on= time_on;
this.pg_type = pg_type;
this.channel = channel;
this.instituteName = instituteName;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public int getTime_on(){
return time_on;
}
public String getPg_type(){
return pg_type;
}
public String getChannel(){
return channel;
}
public String getInstituteName(){
return instituteName;
}
public static MyDean getDeanObject(){
return yz01;
}
}
//成员类——————内部定义好对象,提供对象出口方法
public class Chengyuan {
String name ;
String birth;
int age;
private Chengyuan(String name, String birth ,int age){
this.name = name;
this.birth = birth;
this.age = age;
}
public static Chengyuan creatChengyuanObject(String name, String birth ,int age){
Chengyuan chengyuan = new Chengyuan(name,birth,age) ;
return chengyuan;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public String getBirth(){
return birth;
}
}
//主函数
public class ShowPG {
public static void main(String[] args){
MyDean yz= MyDean.getDeanObject(); //当返回值是Object时可以用(MyDean)进行强制转换
System.out.println(yz.getName());
System.out.println(yz.getAge());
System.out.println(yz.getTime_on());
System.out.println(yz.getPg_type());
System.out.println(yz.getChannel());
System.out.println(yz.getInstituteName());
Chengyuan c1 = Chengyuan.creatChengyuanObject("Stefan","19940410",27);
Chengyuan c2 = Chengyuan.creatChengyuanObject("Eazin","19940420",27);
Chengyuan c3 = Chengyuan.creatChengyuanObject("Jz","19961116",25);
Chengyuan c4 = Chengyuan.creatChengyuanObject("QDZ","19940413",27);
System.out.println("姓名:"+c1.getName()+"生日: "+c1.getBirth()+"年龄:"+c1.getAge());
System.out.println("姓名:"+c2.getName()+"生日: "+c2.getBirth()+"年龄:"+c2.getAge());
System.out.println("姓名:"+c3.getName()+"生日: "+c3.getBirth()+"年龄:"+c3.getAge());
System.out.println("姓名:"+c4.getName()+"生日: "+c4.getBirth()+"年龄:"+c4.getAge());
}
}
命令行运行.java文件(先大致记录一下流程,后续再补齐)
- 将代码放到.txt后缀名改成.java。
- cmd进入存放这个文件的目录。
- javac 文件名。同根目录下生成class文件。
- cmd中用javap -e 文件名(反汇编看指令)。