引子:高德纳技术成熟度曲线
问世初期:掌声雷动好评如潮,期望值被拉高,所有语言/架构都蹭“面向对象”的热点
逐步推广:各种问题慢慢浮现,希望越大失望越大,巨大落差,面向对象(OOP)是编程语言发展中的弯路吗?为什么?
归于平静:有好处,但也不是银弹:在最适合的地方使用。到目前为止,面向对象仍然是目前最主流、最有效地处理复杂业务逻辑的手段。(参考:企业级应用)
语法:非常简单,都应该掌握。
理解为什么:至少要明白“迫不得已”,面向对象是被逼出来,而不是设计出来的!
有意识使用:至少能合理的界定“类的职责”,知道要“避免继承的滥用”,尝试使用多态
方法:观察别人(第三方类库)是如何组织使用的
关于设计模式:两年工作经验以下的新人不建议深究。
没写够十万行代码,不要跟我谈设计模式。
因为面向对象(设计模式)解决的是代码的组织(高级)管理问题。
你接触的项目规模有限,对代码复杂性的理解有限,很难体会“面向对象”的作用。
仍然使用C#,因为:
另外:
我们说过,学习完变量赋值分支循环,理论上我们就可以干任何事情了。从函数开始,我们就从代码实现步入了代码管理的领域。
几千上万行的时候,我们可以用几十个函数实现对代码的组织重用,但随着代码量的进一步增加,代码行数以万计数以十万级,函数都数以千计数以万计的时候,我们怎么办呢?光是记忆这些函数,人脑都相当吃力了!(而且还有命名,^_^)
注意:牢记这一点,人脑的局限或者特点,使我们不得不求助于面向对象
@想一想@:我们如何管理成千上万的函数?一个简单的办法,就是分
比如,
这样,我们想调用一个控制台方法的时候,就可以先找到控制台(类),然后在控制台中寻找方法。事实上,我们也确实是这样做的:
Console.WriteLine("源栈欢迎你!");
Console就是一个类,点(.)就相当于“的”,WrtieLine()就是方法名。所以整行代码的意思就是:调用Console类的WrtieLine()方法。
演示:F12转到WrtieLine()
我们也可以自己声明(创建)一个类,这需要使用
class Student { }
说明:
现在回头看看我们一直在使用的Program.cs,它也是一个类文件,其中的class就声明了的Program类,Program中又声明了Main()方法。
Main()是一般都是项目的入口函数。即:这个项目开始运行,就会调用Main()函数。
演示:
public static void Study() //public和static的含义后文细讲 { Console.WriteLine("学习使我快乐!"); }
但是,当类越来越多,重名的几率就会越来越大,“命名”就会变得越来越困难。
怎么办?一个办法就是加前缀。;但是,“就比如“学生”,这简直太太普遍了。源栈的学生”(YuanZhan.Student),就好多了;如果还担心源栈有重名,就再加一个“大飞哥的源栈的学生”(Dafeige.Yuanzhan.Student)就是了。实际上,关键字class后面跟的不是类的全名,而是一个部分名 。
部分名之前的前缀就叫做名称/命名空间(Java称之为“包(package)”)。
类的全名是:命名空间+点(.)+部分名,类的名称空间由namespace定义,所以这个类的全名是Yuanzhan.Student。
为什么搞得这么复杂呢?
然而,每次都使用全名,会非常的麻烦!
所以我们可以在类文件的开头,声明该文件中所使用的类,默认的名称空间究竟是啥:
你还一定注意到了我们在Study()方法前面加了一个public关键字,这就是:访问修饰符。
它决定了Study()方法能不能在类的外部被调用(访问),包括:
我们可以在类中再装入一个方法,使用不同的访问修饰符:
private static void learn(int score) { score++; }
演示:
访问修饰符除了可以修饰方法(以及后文讲到的其他类成员),也可以修饰类本身。但类不能使用private。
访问修饰符对于面向对象至关重要,因为依靠它,才能真正的实现:
把方法分门别类的组织起来,装到不同的类里面,这只做到了装,还没有做到封。只有使用了这些访问修饰符,才能保证让类能够封闭一些逻辑(代码实现),开放一些接口(调用方法)。
为什么需要封闭呢?开放不好么?现在不都提倡“开源”么……
咳咳!这个不是这样理解的。比如说:
关键的关键,是要能想象:你不是一个人在战斗!有了你我他,就自然有“私有”(孩子长大了,是不是就会有“隐私权”的要求?)
鉴于同学们目前的开发经验,我只能要求大家记牢两点:
类里面除了可以存放方法,还应该可以存储数据。因为对数据的封装是一个非常普遍的要求。
比如我们要实现一个报到的功能,于是声明了一个Enroll()的方法,现在这个方法:
声明若干个类,类里面存放相应的数据即可。
public class Student { public static string name; public static int age; public static string id; public static bool isMale;
class EnrollResult { public static bool Failed; public static string FailedReason;最后,将类传入函数即可:
public static EnrollResult Enroll(Student student){}
#体会#:(函数参数和返回值)使用自定义类型(Student和EnrollResult),而不是预定义类型:
public static int Enroll(string name){}
在类中存放数据的成员叫做:字段
PS:前面的代码其实是有问题的……
你注意到没有,我们本来是要讲面向对象的,但我们一直都在讲类啊!对象在哪里?
对象是类的实例,所以,实例化一个类就能得到这个类对象。
我擦!什么鬼?
稍安勿躁,^_^,我们有了类的概念,比如学生类,学生类里可以放一些和学生相关的方法或字段。但有些东西是类的静态成员无法体现的,比如学生的姓名:
Student.Name = "阿泰";
学生这个类的姓名都叫“阿泰”?这说不通。我们只能说某一个学生的姓名叫“阿泰”,另一个学生的姓名叫“波仔”,这样才对。当然,阿泰和波仔都有共同的特点,他们都在飞哥的源栈学习(learn()),都有学习成绩(score),等等,所以他们是学生。
那如何获得呢?new一个就可以了:
new Student();
这样我们就得到了一个Student类型的对象。
因为对象通过类创建,我们也可以认为:类是创建对象的模板。
在面向对象的世界里,阿泰和波仔都是对象,而且是Student类的对象,因为他们都具有(能调用)Student类所定义的,但是有各自独立的方法(行为)和字段(状态)。
到此为止,无论是字段,还是方法,我们都在其前面加了static,但其实也可以不用static的:
public /*static*/ string name; public static int age; public /*static*/ void Learn(int score) { study(); score++; }没有static的字段/方法被称之为实例字段/方法,对应于静态字段/方法。
对象只能调用Student类中的实例成员(方法和字段):
new Student().name = "阿泰"; //name是实例的 Student.age = 23; //age是静态的 new Student().Learn(87); //learn()是实例的
PS:静态成员由类名调用
@想一想@以下代码运行的结果:
new Student().name = "阿泰"; Console.WriteLine(new Student().name);结果是不能在控制台输出“阿泰”的。
这是因为new是一个运算符,意味着“构建”,每new一次都会生成一个新的对象。
所以上述代码行1和代码2实际上各自生成了两个不相关的对象,新生成的对象上的name字段没有被赋值,所以只有其默认值空。
因此我们通常会在通过new得到一个对象之后,将其赋值给一个同类型的变量:
Student atai = new Student();
#对比体会#:自定义类型的使用:
int age = 10; let sname = 'atai';
只有通过atai变量指向这个对象,就可以反复的使用了:
atai.name = "阿泰"; Console.WriteLine(atai.name);
注意:我们有时候(日常交流)会把这个变量直接说成对象,有时候(授课)又会区分。大家要根据上下文进行适宜的理解。
另外,不同的对象互不影响(和类的静态成员不同)
注意不要将字段(field)和变量(local variable)混淆:(尤其是当方法调用字段的时候……)
class Student { static int age; //字段:类下面直接声明 static string name = "阿泰"; //可以在声明时赋值 public static void greet() { int age = 18; //变量:方法中声明 age++; //使用的是变量 //如果没有age变量的声明,使用字段age } }
他们还有以下区别(演示):
总结一下:
|
属于 |
由...调用 |
选择 |
静态 |
类 |
类(名) |
一定要有充分的理由才使用 |
实例 |
对象 |
对象 |
优先考虑 |
演示:调用其他类的静态/实例方法
注意他们之间的单向访问问题,即:
在同一类中调用自己类的成员:
多快好省!前端后端,线上线下,名师精讲
更多了解 加: