zoukankan      html  css  js  c++  java
  • 封装

    封装特性为程序设计提供了系统与系统、模块与模块、类与类之间交互的实现手段。隐藏了内部的具体实现细节,对外提供了统一的访问接口,来操作内部数据成员。}

    using System;
    
    namespace ConsoleApp1
    {
        public class ATM
        {
            //定义私有方法,隐藏具体实现
            private Client GetUser(string userID) { }
            private bool IsValidUser(Client user) { }
            private int GetHash(int money) { }
    
            //定义公有方法,提供对外接口
            public void CashProcess(string UserId, int money)
            {
                Client tempUser = GetUser(userID);
                if (IsValidUser(tempUser))
                {
                    GetCash(money);
                }
                else
                {
                    Console.WriteLine("你不是合法用户");
                }
            }
        }
        public class Client
        {
    
        }
        class Program
        {
           
            
            static void Main(string[] args)
            {
              
            }
        }
    }

    字段:通常定义为private,标识类的状态信息。CLR只支持只读和读写字段。只读地段只能在构造函数中被赋值。

    public class Client
    {
      private string name; 
      private int age;
      private string password;          
    }

    我们可以通过类的实例访问和改变字段内容。

     

    public static void Main()
    {
      Client xiaowang = new Client();
      xiaowang.name = "Xiao Wang"
      xiaowang.age = 27;
      xiaowang.password = "123456"    
    }

    同时小王的年龄不可能是1000

    xiaowang.age = 1000

    所以对字段公有化的操作,会破坏对象的状态信息,数据安全性和可靠性无法保证。

    所以,封装的第一个原则就是将字段定义为private

    但是我们对对象的状态信息的控制又该如何实现呢。我们既希望以另外的方式提供给类的外部访问或改变,同时期望实现对数据的访问,因此,加入了另外一个概念,属性。

    属性(property)通常定义为public,表示对类的外部成员,属性具有可读、可写的属性,通过get或set访问器来实现读写控制。

     public class Client
        {
            private string name;
            public string Name
            {
                get { return name; }
                set
                {
                    name = value == null ? String.Empty : value;
                }
            }
    
            private int age;
    
            public int Age
            {
                get { return age; }
                set
                {
                    if ((value>0 && value<150)) {
                        age = value;
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException("年龄信息不正确");
                //异常指定的信息超出了容量的范围 } } }

    因此,属性的实质就是在编译时分别将get和set访问器实现为对外方法,从而达到控制属性的目的,对属性的读写行为伴随的实际是一个相应方法的调用。

    因此,我们也可以定义自己的get和set访问器。

    public string get_Password()
    {
        return password;
    }
    public string set_Password(string value)
    {
         if(value.Length<6){
         password = value;
    }
    }

    这样的方式显然没有实现get和set访问器来得轻便,而且对属性的操作也带来多余的麻烦。下面的这种方式显然更加方便。

    public string Password
    {
        get {return passowrd;}
        set {
             if(value.Length<6){
                  password = value;
        }
        }
    }        

    相应的属性只读只需要实现get,属性为只写,只需要实现set.

    通过对公共属性的访问来实现对类状态信息的读写控制,1是避免了对数据安全的访问限制,保证了内部数据的可靠性,二是避免了类拓展或者修改所带来的连锁反应。

    至于修改变量带来的连锁反应,表现在对类的状态信息的需求信息发生变化时,如何来减少代码重构的基础上实现最小的损失和最大的补救。如client的用户姓名由简单name标识,换成FirstName和secondName

    来实现,如果不是属性封装了字段而带来的隐藏内部细节的特点,就要拼命地替换为xiaoWang.name来实现。

    private string firstName;
    private string secondName;
    
    public string Name
    {
        get { return firstName + secondName; }
    }

    方法封装了类的行为,提供了类的对外表现。用于将封装的内部细节以公有方法提供对外接口,从而实现与外部的交互和相应。

    封装的意义:

      通过对字段、属性和方法在封装性上这一点的分析。

      (1)字段通常为private,属性通常为public.而方法在内部实现为private,对外实现为public.从而保证对内部数据的可靠性读写控制,保证了数据的安全性和可靠性。同时又提供了与外部接口的有效交互。

      (2)封装的意义不知类设计层面对字段、属性和方法的控制,更重要的是广义层面,一个系统或软件开发之后,从维护和升级的目的考虑,一定要保证对外几口部分的绝对稳定。不管系统内部的功能性实现如何多变,保证接口稳定一定是保证软件兼容、稳定、健壮的根本。

          因此,OO智慧中的封装性旨在保证:

      隐藏系统实现的细节,保证系统的安全性和可靠性。

      提供稳定不变的对外接口。因此,系统中相对稳定的部分常被抽象为接口。

      封装保证了代码模块化,提高了软件的服用和功能分离。

      

      封装的规则:

        尽可能调用类的访问器,而不是成员,即使实在类的内部。

                  内部私有部分可以随意更改,但是一定要保证外部接口稳定的前提下。

        对字段的读写控制实现为属性,而不是方法。

  • 相关阅读:
    【更新】Java发送邮件:个人邮箱(QQ & 网易163)+企业邮箱+Android
    git pull 出现 WARNING: POSSIBLE DNS SPOOFING DETECTED!
    Redis解决“重试次数”场景的实现思路
    IDEA更改JavaScript版本
    npm与yarn命令
    SpringBoot+Vue前后端分离项目,maven package自动打包整合
    Vue(九)使用Ant Design入门——环境搭建
    Git常用命令
    Vue(八)全局变量和全局方法
    笔记本电池怎样使用问题
  • 原文地址:https://www.cnblogs.com/maxuefeng/p/15620811.html
Copyright © 2011-2022 走看看