黑马程序员-面向对象,封装

-----------android培训java培训、java学习型技术博客、期待与您交流! ------------


一、面向对象

1、面向对象概念


面向对象就是把多个功能封装到一个对象中,通过调用该对象获取这些功能。称为面向对象。

2、面向对象和面向过程的理解:


面向对象是相对面向过程而言
面向对象和面向过程都是一种思想:面向过程强调的是功能行为;面向对象将功能封装进对象,强调具备了功能的对象。
面向对象是基于面向过程的。

3、事例


事例1:
门具有打开,关闭功能等等。这些功能都需要门来完成的,那么就将这些功能封装进门这个对象中,我们只要调用门这个对象,通过门就能使用这些功能。
事例2:
举例来说:就是:比如说你要去饭店吃饭,你只需要饭店,找到饭店的服务员,跟她说你要吃什么,然后过会给你做出来让你吃,你并不需要知道这个饭是怎么做的;然后她也只需要面向你吃完收到钱就好,不需要知道你怎么对这个饭进行吃。

4、开发的实质:


开发的过程:其实就是不断的创建对象,使用对象,指挥对象做事情。
设计的过程:其实就是在管理和维护对象之间的关系。

5、面向对象的特征:


封装(encapsulation)
继承(inheritance)
多态(polymorphism)

6、对面向对象的特征的理解:


面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节;这种思想是将数据作为第一位,而方法或者说是算法作为其次,这是对数据一种优化,操作起来更加的方便,简化了过程。

面向对象有三大特征:封装性、继承性、多态性,其中:

(1)封装性指的是隐藏了对象的属性和实现细节,仅对外提供公共的访问方式,这样就隔离了具体的变化,便于使用,提高了复用性和安全性。

(2)对于继承性,就是两种事物间存在着一定的所属关系,那么继承的类就可以从被继承的类中获得一些属性和方法;这就提高了代码的复用性。继承是作为多态的前提的。

(3)多态是说父类或接口的引用指向了子类对象,这就提高了程序的扩展性,也就是说只要实现或继承了同一个接口或类,那么就可以使用父类中相应的方法,提高程序扩展性,但是多态有一点不好之处在于:父类引用不能访问子类中的成员。


二、类与对象


1、类和对象的关系

java中描述事物通过类的形式体现,类是一组相同属性行为的对象的抽象。
对象即是该类事物实实在在存在的个体。
举例:人就是一个类(是把每一个相同属性行为的对象进行抽取)人的属性:姓名,年龄,身高,体重等,人的行为:吃饭,睡觉,说话,跑,跳等。
而我们就是对象(是实实在在存在的个体),具体每个人叫什么名字,年龄多大,身高多高,体重多重等,吃饭怎么吃,睡觉怎么睡,说话怎么说等。

其实定义类,就是在描述事物,就是在描述事物的属性和行为。属性和行为共同称为类中的成员(成员变量和成员方法)。


2、成员变量和局部变量的区别:


1)作用范围。
成员变量:定义在类中,作用于整个类。
局部变量:只在它所属的局部大括号中有效。比如函数上的参数,函数中的变量,语句中的变量。
public void function(int x){//x,y,z都是局部变量。
	int y = 0;
	for(int z=0; z<3; x++){
	}//当循环结束时,z在内存中释放。当function函数执行完毕,x和y在内存中释放。
}

2)存储情况。
成员变量:存储在堆内存中,随着对象的存在而存在。当对象变成垃圾被回收时,该该对象中的成员变量会消失。
局部变量:存储在栈内存中,当方法被调用,或者语句被执行的时候,才存在。
当方法运行完毕,或者语句运行完毕时,局部会被自动释放。所以成员变量也称之为实例(对象)变量.
3)初始化情况。
成员变量:在堆内存中有默认初始化值。
局部变量:没有默认初始值,使用前必须赋值,不初始化是不能参与运算的。

3、匿名对象:


所谓的匿名对象,就是创建对象的时候没有给对象起名字就直接使用。
使用方式:
1)使用方式一:当对对象的 方法 只调用一次时,可以使用匿名对象来完成,这样写比较简化。
      如果对一个对象进行多个成员调用,必须给这个对象起个名字
2)使用方式二:可以给匿名对象作为实际参数进行传递,从而可以不用在main方法中创建一个变量,提高了编程效率,减少了代码书写。
      但是这个对象实体在方法结束后,垃圾回收机制会将其作为垃圾回收。而非匿名对象则不同,当不使用了,会在某一时刻被回收,或是随着主函数的结束而被回收。
匿名对象常见错误理解:
如:
1:new Car().num = 5; 
2: new Car().color = "blue";
3:new Car().run();//假设有run方法能调用num和color属性
new三次就是三个匿名对象。3方法打印出来的不是1,2所定义的属性。因为三者没有关系。属于三个对象了

所以,匿名对象调用属性没有意义


三、封装


封装性是面向对象程序设计的原则之一。它规定对象应对外部环境隐藏它们的内部工作方式。良好的封装提高了代码的模块性,它防止了对象之间不良的相互影响, 这样就使得未来的开发工作变得容易。

     封装定义:是指隐藏对象的属性和实现细节,仅对外提供公共的访问方式。

     封装好处:1)将变化隔离。2)便于使用。3)提高重用性。4)提高安全性。

     封装原则:1)将不需要对外提供的内容都隐藏起来。2)把属性都隐藏,提供公共方法对其访问。


代码示例:

    class Person

    {

           private int age;//只在本类中有效,不能被其他对象直接访问了

           public void setAge(int age)//提供了对外的公共方法

           {

              this.age=age;

              System.out.println(this.age);

             }

     }

     class Demo

    {

          public static void main(String[] args)

          {

             Person p=new Person();

             p.setAge(12);

          }

     }

    通常情况下,会将类中的成员变量私有化,以避免属性直接被访问导致数据错误;同时对外提供了公共的访问方式,对该属性进行间接访问。

    变量私有化用private关键字修饰。private关键字的含义:除了包含该成员的类之外,其他任何类都无法访问这个成员。

    对属性访问的公共方法名称定义格式:set属性()、get属性()。若对象中有10个属性,一般则至少有20个方法,因为每个属性通常都对应两个方法:set属性();get属性()

    注意:私有仅仅是封装的一种体现形式之一。函数就是一个最小的封装体。类本身也是一种封装。

    通过上例我们可以看出: 建构具有良好封装性能的对象的第一个步骤就是getter/setter 对访问私有数据域。通过一个控制的机制来要求那些要对对象的域进行读和写的其他对象这样去做, 可以加强法定值和内部数据的连贯性。如果有一个域名为duration, 它应该保存一个正整数, 当另一个对象试图进行setduration(-4) 时,就可以给出一个illegalargumentexception。如果将duration 成员设置为公有,就不能防止某人调用yourobject.duration=-4并搞乱数据的内部连贯性。

通过一个例子来理解这个问题: 编写一个教师类, 要求:

      (1) 具有属性:姓名、年龄

      (2) 具有行为:自我介绍

      (3) 教师的最小年龄要求: 22 岁

public class teacher

{

     public string name; // 教员姓名

     public int age; //年龄

     /**

    * 返回自我介绍的内容

    */

   public string introduction () {

         return “ 大家好!我是” + name + “,我今年” + age+”“ ;

     }

}

编写一个测试类, 要求: 实例化一个教员对象, 并对其初始化, 并在控制台输出该教员的自我介绍。

public class teachertest {

 

    public static void main (string [ ] args) {

               teacher teacher = new teacher () ;

               teacher.name = “ 张三” ;

               teacher.age =9;

              system.out.println (teacher.introduction ()) ;

     }

}
     运行结果为: 大家好! 我是张三, 我今年9 岁
     因为没对属性进行封装, 所以运行结果不满足教员的最小年龄要求, 要满足此要求, 就需要通过对属性的封装来实现,修改teacher 类如下:

public class teacher {

     private string name; // 教员姓名

     private int age; //年龄

     public int getage () {

                return age;

      }

     public void setage (int age) {

                if (age<22) {

                            system.out.println (“ 错误!最小年龄应为22 岁!”) ;

                            this.age = 22; //如果不符合年龄要求,则赋予默认值

                }

              else {

                           this.age = age;

                }

       }

       public string getname () {

              return name; // 返回教员姓名

       }

      public void setname (string name) {

              this.name = name; // 设定教员姓名

       }

     public string introduction () {

             return “ 大家好!我是” + name + “,我今年” + age+”岁” ;

       }

}

       现在同样执行以上测试类teachertest, 运行结果为:错误! 最小年龄应为22 岁!

       大家好! 我是张三, 我今年22 岁


从以上事例可得出: 使用封装, 增加了数据访问限制,增强了程序的可维护性, 其封装步骤为:

   (1) 修改name、age 属性的可见性为private 来限制直接对属性的访问。

   (2) 为每个属性创建一对赋值(setter) 方法和取(getter)方法, 用于间接对这些属性的访问。

   (3) 在setter 和getter 方法中, 加入对属性的存取限制。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值