A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© yangjijin 中级黑马   /  2014-7-3 10:26  /  1877 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

封装[20分钟]
1)        为什么需要封装
a)        通过以下示例来分析
1.        编写一个Person类,要求:
a)        具有属性:姓名、年龄
b)        具有行为:自我介绍
2.        以上要求很容易实现,代码如下:
class Person01 {
        public String name = "tom";        //姓名
        public int age = 20;                        //年龄
        public void salaryInfo() {
                System.out.println("大家好,我是:" + name + "\t年龄是:" + age);
        }
}
b)        现在实例化一个对象来测试创建的类是否符合要求:
1.        代码示例:
public class Demo001 {
        public static void main(String args[]) {
                // 创建“人”类对象
                Person01 person = new Person01();
                // 为人类对象的属性赋值————很明显,这个值不符合实际情况:没有人的年龄会是1000
                person.age = 1000;
                person.salaryInfo();
        }
}
2.        输出结果:

3.        以上结果不符合要求(没有人的年龄会是1000),如何解决呢?
c)        要满足年龄要求,可以通过对属性的封装来实现
2)        什么是封装
a)        封装:就是隐藏实现细节
1.        将属性私有化,提供公有方法访问私有属性
2.        通过这些公有方法访问私有属性
b)        代码示例:
class Person02 {
        // 私有的属性
        private String name = "tom";
        // 对name属性进行封装
        //如果只有get封装,表明属性是只读的
        //如果只有set封装,表明属性是只写的
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }
}
public class Demo002 {
        public static void main(String args[]) {
                // 创建“人”类对象
                Person02 person = new Person02();
                person.setName("张三");
                String sName = person.getName();
        }
}
3)        如何实现封装
a)        封装的实现:
1.        修改属性的可见性来限制对属性的访问
2.        为每个属性创建一对赋值(setter)方法和取值(getter) 方法,用于对这些属性的访问
3.        在setter和getter方法中,加入对属性的存取限制
b)        代码示例:
class Person02 {
        // 私有的属性
        private int age = 20;

        // 对age属性进行封装
        public int getAge() {
                return age;
        }
        // 在属性封装中将年龄限制在0~100之间
        public void setAge(int age) {
                if (age < 0 || age > 100) {
                        System.out.println("年龄必须在0~100之间,将使用默认值!");
                } else {
                        this.age = age;
                }
        }
}
c)        使用封装好的属性:
1.        测试类:
a)        通过调用setter方法,为对象的各个属性赋值
b)        通过调用getter方法,获取对象的各个属性赋值

public class Demo002 {
        public static void main(String args[]) {
                // 创建“人”类对象
                Person02 person = new Person02();
                person.setName("张三");
                // 为人类对象的属性赋值————很明显,这个值不符合实际情况:没有人的年龄会是1000,
                // 而这里,因为有封装,程序不会将1000赋值给age变量
                person.setAge(1000);
                person.salaryInfo();
        }
}

d)        使用封装,增加了数据访问限制,增强了程序的可维护性
4)        访问修饰符
a)        Java访问控制符的作用是说明被声明的内容(类、属性、方法和构造方法)的访问权限
b)        private是访问修饰符的一种,除了private之外,还有默认(无访问修饰符)、protected、public

c)        示例:

5)        小结
a)        封装的具体步骤
1.        修改属性的可见性限制对属性的访问
2.        为每个属性创建一对赋值方法和取值方法,用于对这些属性的访问
3.        在赋值和取值方法中,加入对属性的存取限制
b)        编程:
1.        请通过代码封装,实现如下需求:
a)        编写一个类Book,代表教材:
1)        具有属性:名称(title)、页数(pageNum),其中页数不能少于200页,否则输出错误信息,并赋予默认值200
2)        为各属性设置赋值和取值方法
3)        具有方法:detail,用来在控制台输出每本教材的名称和页数
b)        编写测试类BookTest进行测试:为Book对象的属性赋予初始值,并调用Book对象的detail方法,看看输出是否正确
2.        代码示例:
class Book {
        // 名称
        private String title;
        // 页数
        private int pageNum = 200;
        public String getTitle() {
                return title;
        }
        public void setTitle(String title) {
                this.title = title;
        }
        public int getPageNum() {
                return pageNum;
        }
        //通过封装,限制页数必须大于200
        public void setPageNum(int pageNum) {
                if (pageNum < 200) {
                        System.out.println("页数不能少于200页,将使用默认值200");
                        this.pageNum = 200;
                } else {
                        this.pageNum = pageNum;
                }
        }
        // 在控制台输出每本教材的名称和页数
        public void detail() {
                System.out.println("名称:" + this.title + "\n页数:" + this.pageNum);
        }
}
/*
* 测试类
*/
public class BookTest {
        public static void main(String[] args) {
                Book book = new Book();
                book.setTitle("JAVA基础教程");
                book.setPageNum(177);
                book.detail();
        }
}
知识点2:构造方法[15分钟]
1)        为什么需要构造方法
a)        只要创建对象,就一定会使用到构造方法
b)        通过以下示例来分析:
1.        开发Person类:Person04,要求:
1)        具有属性:姓名、年龄、性别、地址
2)        具有行为:自我介绍
2.        代码示例:
class Person04 {
        // Person的四个属性
        private String name;
        private String address;
        private String sex;
        private int age;
        // 以下是对属性的封装
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }
        public String getAddress() {
                return address;
        }
        public void setAddress(String address) {
                this.address = address;
        }
        public String getSex() {
                return sex;
        }
        public void setSex(String sex) {
                this.sex = sex;
        }
        public int getAge() {
                return age;
        }
        // 在属性封装中将年龄限制在0~100之间
        public void setAge(int age) {
                if (age < 0 || age > 100) {
                        System.out.println("年龄必须在0~100之间,将使用默认值!");
                } else {
                        this.age = age;
                }
        }
        public String sayHai() {
                return "大家好!我是:"+this.name+",我今年:"+this.age+"岁,性别:"+this.sex+",地址是:"+this.address;
        }
}
c)        编写一个测试类,要求:
1.        实例化一个教员对象,并对其初始化
2.        在控制台输出该教员的自我介绍
3.        代码如下:
/*
* Person中有太多的属性及对应的setter方法,
* 在初始化时,很容易就忘记了
* 以下代码没有初始化地址
* 所以地址就是String类型的默认值:null
*/
public class Demo004 {
        public static void main(String[] args) {
                Person04 person = new Person04();
                person.setName("张三");
                person.setAge(23);
                person.setSex("男");
                System.out.println(person.sayHai());
        }
}
4.        输出如下:

5.        可能出现的问题:
1)        Person04中有太多的属性及对应的setter方法,在初始化时,很容易就忘记了,有没有可能简化对象初始化的代码?
d)        要简化对象初始化的代码,可以通过构造方法来解决
2)        什么是构造方法
a)        构造方法负责对象成员的初始化工作,为实例变量赋予合适的初始值
b)        构造方法必须满足以下语法规则:
1.        方法名与类名相同
2.        没有返回类型
c)        代码示例:
public class Person10 {
        public String name;  // 姓名
        // 构造方法
        public  Person05 () {
        name = "无名氏";
        }
}
d)        使用new关键字调用构造方法
1.        代码示例:
public class Demo009 {
        public static void main(String[] args) {
                Person10 person = new Person10();
                System.out.println(person.name);
        }
}
e)        在以上代码示例中,即使没有给person对象的name属性赋值,name属性也有一个初始值:无名氏
f)        很多时间,我们希望显示地为实例变量赋予初始值:在不同的条件下创建不同的对象。所以我们需要使用带参数的构造方法
3)        带参数的构造方法
a)        通过带参数的构造方法,显式地为实例变量赋予初始值
1.        代码示例:
class Person05 {
        // Person的四个属性
        private String name;
        private String address;
        private String sex;
        private int age;
        //带四个参数的构造方法
        public Person05(String name, String address, String sex, int age) {
                this.name = name;
                this.address = address;
                this.sex = sex;
                this.setAge(age);//调用封装的方法,以实现对年龄的限制
                //this.age = age;
        }
        // 以下是对属性的封装
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }
        public String getAddress() {
                return address;
        }
        public void setAddress(String address) {
                this.address = address;
        }
        public String getSex() {
                return sex;
        }
        public void setSex(String sex) {
                this.sex = sex;
        }
        public int getAge() {
                return age;
        }
        // 在属性封装中将年龄限制在0~100之间
        public void setAge(int age) {
                if (age < 0 || age > 100) {
                        System.out.println("年龄必须在0~100之间,将使用默认值!");
                } else {
                        this.age = age;
                }
        }
        public String sayHai() {
                return "大家好!我是:"+this.name+",我今年:"+this.age+"岁,性别:"+this.sex+",地址是:"+this.address;
        }
}
b)        通过调用带参数的构造方法,简化对象初始化的代码
1.        代码示例:
/*
* Person类有一个构造方法,
* 在创建对象时,将使用这个构造方法,
* 如果没有提供所需参数,就会出现编译错误
* 可以及时提醒
*/
public class Demo005 {
        public static void main(String[] args) {
                Person05 person = new Person05("张三","北京","男",23);
                System.out.println(person.sayHai());
        }
}

3 个回复

倒序浏览
挣分不容易啊,加油!
回复 使用道具 举报
封装??
回复 使用道具 举报
感谢楼主分享
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马