纵观MicroSoft公司的几种主流语言,C是面向过程,VB既有面向过程也有面向对象的特性,而C#则是纯粹的面向对象的编程语言。在UML的学习过程中,画类图、对象图的时候面向对象的思想就已经用到了具体的学习中,而C#的学习过程中我们接着深入来学习这种思想,只不过这次是把OOP的思想用到了实际的代码编程之中。
我们知道面向对象的四个基本原则:抽象、封装、模块化、层次性;面向对象思想的编程特性:继承性、封装性、多态性。通过楚老师的视频,对面向对象的四个基本原则和编程特性都有了新的认识,这篇博客就先对其中的部分特性进行分析。
在上一篇博客中,对C#基础的分析是以“数据”引出来的,数据中变量在程序设计中占有一席之地,那我们就从静态变量和非静态变量两个角度对它进行分析。
using system;
using system.Collections.Generic;
using System.text
namespace ConsoleApplication1
{
class TestStatic
{
public static void main()
{
int k=AccessTest.x; //此处直接使用,如果不是静态变量则写成 AccessTest myOk = newAccessTest();
Console.WriteLine(k);
AccessTest myOk=new AccessTest();
Cosole.WriteLine(myOK.y); //通过实例化才能访问y
}
}
public class AccessTest
{
public static int x=12;
public int y=12;
}
}
由例子可知,在AccessTest类中定义了两个变量x和y,其中x为静态static,y为非静态,在TestStatic类的Main函数如果要分别对AccessTest类中的x和y进行访问,则对于x可以直接使用,而对于y需要首先实例化AccessTest类,然后再由该实例去调用其中的y。也就是说静态变量中的成员可以通过类名直接进行访问,而实例成员(非静态变量)必须通过建立对象的引用来访问(此处区别对象和对象引用,对象引用是一个地址而不是一个值)。我想如果x和y都定义成了非静态变量的话,那样代码量会大增的。
通过学习,对static变量有了自己的认识,但是理解的程度仅限于此,至于在代码中何处该用静态变量,还有待于在以后的学习中去探索。
所谓的方法,就是对象的行为,在之前学习VB的时候对象有属性、事件和方法,而在真正面向对象的语言中没有事件的概念,或者说事件就是属于方法中的。
方法的句法如下:
[访问修饰符] 返回值类型 <方法名> ([参数列表])//不需要返回值时用void
{
//方法主体
}
正如上面介绍的静态变量和非静态变量那样,调用静态的方法同样无需进行实例化,而非静态的方法需要进行类的实例化之后进行调用该方法。
方法可以被重复调用即“方法重载”在C#中是一个非常重要的定义,视频中老师将其分为“具有不同数量参数的方法重载”和“对不同数据执行相似功能的方法重载”,如下:
Using System;
Namespace chognzai
{
Class Class1
{
Public int a,b;
Public double x,y;
Public int fun(int a,int b) //方法名称相同,参数不同
{
Return a+b;
}
Public double fun(double x,double y) //方法名称相同,参数不同
{
Return a+b;
}
Static void Main(string[] args)
{
Class1 sd=new Class1();
Sd.a=156;
Sd.b=32;
Sd.x=23.56;
Sd.y=56.49;
Console.WriteLine(“{0}+{1}={2}”,sd.a,sd.b,sd.fun(sd.a,sd.b));
Console.writeLine(“{0}+{1}={2}”,sd.x,sd.y,sd.fun(sd.x,sd.y));
Console.ReadLine();
}
}
}
该例子中成员函数fun()被重载,属于“对不同数据执行相似功能的方法重载”,再次验证了方法是可以多次使用的这个观点。
先看个小例子,这是在视频中非常经典的那个交电话费的例子。
namespace Customer
{
public enum TypeofCall
{
callToMobile,CallTOLandLine
}
class Program
{
static void Main(string[] args)
{
Customer tom=new Customer();
tom.CustomerName="楚广明"; //设置属性的值
tom.RecordCall(TypeofCall.callToMobile,20);
tom.RecordCall(TypeofCall.callToLandline,40);
Console.WriteLine("{0}有{1}电话费要交",tom.CustomerName,tom.customerBalance) //读取属性的值
}
}
public class Customer
{
private string name;
private decimal balance;
public string CustomerName //*****属性****//
{
get( return name;)
set ( name=value;)
}
public decimal CustomerBalance //****属性***//
{
get ( return balance;) //只能读取余额,而不能修改
}
public void RecordPayment(decimal amountpaid) //***方法*** //
{
balance-=amountpaid;
}
public void RecordCall(TypeofCall callType,uint nMinute) //***方法*** //
{
swistch(callType)
{
case TypeofCall.CallToLandline:
balance+=(0.02M*nMinutes);
break;
case TypeofCall.callToMobile:
balance+=(0.3M*nMinutes);
default:
break;
}
}
}
}
例子有点长,其中仅仅对属性进行分析,就像:
public string CustomerName //*****属性****//
{
get( return name;)
set ( name=value;)
}
public decimal CustomerBalance //****属性***//
{
get ( return balance;) //只能读取余额,而不能修改
}
这两个属性是这个例子中的Customer类实例化后tom对象的两个属性,很明显属性区别于方法就像当初学习VB一样,一个说明的是属性,另一个说的是动作。从这个例子中还能体现出面向对象封装性的思想,就像CustomerBalance属性那样,仅仅为读取属性,而没有设置属性的代码,这样我们在主程序中就不能去修改,从而保护了隐私。也就是说通过属性,将类的成员变量隔离,通过赋值、取值实现间隐藏封装的功能,这也可以看做是一种权限的限制。
通过这个小例子,OOP的封装性也就是通过其他间接的手段去操作类的成员变量,不要让别人知道你的成员变量中包含着什么,当然这里所谓的间接手段可以是上面所提到的属性,也可以是方法,前提是该方法的访问修饰符是public,通过该方法调用相同类中访问修饰符为private的成员变量或者成员方法,从而实现封装,在C#视频中有个“访问密码的最短长度(private)”的例子就是通过这个方法实现的。
在C#中面向对象的思想吗,目前仅仅是了解,需要急切去做的就是到《设计模式》的时候多去敲例子,多去回顾现在学的这些东西,带着问题去学新知识,从而实现“温故而知新”的效果。
在接下来的面向对象总结中将对“继承、多态”做浅析,期待。