类(人)——对象(孙权)。在main函数中创建类的对象(孙权)。类区分结构:类是面向对象的,结构是面对过程的。结构挺少用的。
private是public的反义词,局部变量。默认是private。
有get又有set的属性叫做可读可写属性。
被static标记的就是静态成员:可以是静态类、静态方法、静态字段、静态属性。这些都要通过类调用。
动态函数p.M1()可以调用静态成员如静态字段;静态函数P.M2()不可以调用实例成员如gender
Console就是系统内置的静态类,里面所有的成员都是静态成员。调用里面的成员都用通过类名Console。正是因此,静态函数里面没必要实例化对象,调用都得通过类名。
构造函数是可以有重载的: 即可以选择传进不同长度的参数
this:(1)表示当前这个类的对象(在定义类时);(2)构造函数互相调用。下图中的this代表的是全参的构造函数student。new产生的对象表面上是通过半参的构造函数student形成,但本质上,是由全参的构造函数student构建而成。
析构函数:在类名前面加~没有返回值。对象执行结束后执行。作用回收内存空间。 ~Demo3()
命名空间:(1)用于区分不同的类的重名问题。(2)跨项目的引用类。
类的存放文件夹:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;
跨项目的引用类。想在02项目中引用01项目的类:
内存中有两块存储空间:堆、栈。堆里的内存能够以任意顺序存入和移除。栈是后进先出。
继承:
子类的构造函数student,通过base调用父类的构造函数person。
推荐一个讲c#特别清楚的博主,她其他文章有时间可以看看:https://www.cnblogs.com/longxinyv/p/14428175.html
//ref:https://www.cnblogs.com/longxinyv/p/14428175.html
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//namespace(命名空间)用于解决类重命名问题,可以看做类的文件夹。
//如果代码和被使用的类在同一个namespace命名空间下则不需要using来引用。如果不在就需要using 命名空间.类名来调用。
namespace CSharp
{
//面向过程:面向的是完成这件事情的一个过程,强调的是完成事情的一系列动作。如:把对象放进冰箱里的一个过程。强调动作1.首先要打开冰箱门,2.在把大象放进去,3.最后关闭冰箱门。
//假如张三去处理刚好能操作,而李四他太矮了没办法操作,需要借助凳子,才能把大象放进冰箱。
//如果使用面向过程思想来解决问题,如果执行这件事情的人不同,我们就需要为每个人都去量身定做解决事情的方法。对应每个人代码都不同。
//面向对象:找个对象不能做事情。意在写出一段通用代码,屏蔽差异。
//如:冰箱可以被打开,大象可以被放进冰箱,冰箱门可以被关闭。不管是谁的可以做这件事情。
//对象思维:在数学家眼里为马上理想到数字。程序员而言万物皆对象。
//关门:面向过程是主动的:张三轻轻地把门带上了,李四一脚把门踹紧了。面向对象是被动的就一句代码解决所有人的关门:没可以被关闭。
//对象的特征:对象必须是看得见摸得着的,我们描述一个对象,通常是通过对象的属性和方法去描述的。如钢笔是对象,属性(值):一只红色的钢笔,带图案的钢笔等等。方法(行为,执行的操作)
//类(相当于设计图子):就是一个模板。把一些具有相同属性和方法的对象进行了封装,抽象出来 类 的这个概念。
//对象(设计结果)对象是根据类创建出来的(先有类在有对象):人类,孙权是人类中的对象,属性就是,姓名,年龄,身高等等一系列特征,方法(行为,动作,执行的一系列操作):吃喝拉撒睡等等。
///
/// 不是系统提供的称自定义类,通常来说一个类,就是一个文件,这里为了方便看写在一个文件里面了。类起到的就是一个封装的效果。
///
public class Demo
{//类的三要素:字段,属性,方法
string _name;//字段:存放数据的一个东西,不应该让外部随便访问,当我们给字段存值时不想让用户随便乱输入。这个时候属性作用就出现了。
public string Name //(属性的作用就是保护字段,对字段的赋值和取值进行限定)//应该给每个字段都配备属性。
{//基本写法:
get { return _name; }//当你输出字段的时候执行get方法
set { _name = value; }//给字段赋值的时候会执行set方法,将value赋值给name。value值是set访问器自动的字段,作用将外部值传递进来并赋值给对应字段。
}
int _age;
public int Age //属性的限定
{
get { return _age; }
set
{
if (value > 100 || value < 0) value = 0;//限定了年龄不能为负值
_age = value;
}
}
//方法--输出值是输出属性的值而不是输出字段的值,这样才能进入get和set限定。
public void A() { Console.WriteLine("我是{0},今年{1}岁。", this.Name, this.Age); } //this关键字的作用:表示当前类的对象。
}
///
/// 我们需要的不是类,而是类下面的对象,类是看不见的,对象是实在的,我们操作最多的就是对象。
///
class Demo2
{
static void Main(string[] args)
{
//实例化对象:写好了一个类后我们需要创建这个类的对象,我们把这个创建过程称为类的实例化,正是因为需要的是对象俗称过程为:实例化对象
Demo d = new Demo();//类名 变量名 = new 类名();
//对象的初始化:创建好类对象后,需要给对象的每个属性一次去赋值,这个过程叫初始化过程。
d.Name = "张三";//变量名.字段名/方法名()来调用
d.Age = 18;
d.A();//调用方法。也是对象
Demo d2 = new Demo();//类本身不占内存,而对象是占内存的,每次实例化后类里面的对象都会初始化值。
d2.Name = "李四";
d2.Age = -11;//赋值会走set方法,对属性限定。
d2.A();
//------------------------------------------------------------------------------------------
string s;//string也是一个类,系统类
Demo2 ss;//Demo2就是自定义类。 ss就是Demo2类型的一个变量。
//构造函数:给对象初始化。实例化对象首先会执行的是构造函数
Demo3 d3 = new Demo3("给构造函数传参数:");//new做3个件事:1.在内存开辟一个新空间,2.在开辟空间中创建对象,3.调用对象构造函数进行初始化对象。
Console.WriteLine(d3.name+d3.age);
Console.ReadKey();
Console.ReadLine();//利用接收输入来暂停程序,避免程序一闪而过
}
}
//构造函数:作用初始化对象的特殊方法,方法名必须和类名一样,没有返回值,连void不能写。他可以被重载,可以有参数,new 对象的时候(参数在括号里面传进来即可)所有方法是在new对象的时候执行。
class Demo3
{
public Demo3() { Console.WriteLine("每个类中如果不指定构造函数,默认自带一个无参构造函数,指定了(有参)构造函数,则默认消失,如需要时,要重新定义无参构造。"); }
public string name;
public int age;
//定义一个有参构造函数
public Demo3(string a,int i)
{
this.name = a;
this.age = i;
}
public Demo3(string a) : this(a,18) { }//this关键字的一个作用:调用当前类的构造函数。实例化对象时只需要传一个参数,实际上调用上面的构造函数
//析构函数:在类名前面加~没有返回值。对象执行结束后执行。作用回收内存空间。
~Demo3() { Console.WriteLine("当程序结束时会执行这个【析构函数】,析构函数作用通常用来释放资源。如果不使用析构,就只能等垃圾回收器自动回收。"); Console.ReadLine(); }
}
}
//----------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//继承:一个类继承类一个类 class B:A 意思是将子类B继承自父类A,或者说派生类B继承了基类A。继承后B类将拥有A类所有的成员(私有的不能使用)所有类都继承自object类。
//构造方法执行过程:先执行父类构造在执行子类构造。如果父类定义了构造方法,子类必须实现其中一个。
//继承的特性:1.单继承,单根性:一个子类只能继承一个父类;2.传递性:B继承A,然后C继承B,那么c就有了B和A的所有成员。
//多态:父类的一个方法,在不同子类中可以有不同的实现(叫方法重写)父类定义虚方法关键字 virtual,子类重写虚方法关键字 override
namespace CSharp
{
class jicheng //继承:子类继承父类,单继承:只能一个父类。需要用父类下面的成员,所有要继承,另外就有了抽象类,和接口:抽象类中的抽象类,提供方法让子类去实现。
{
static void Main()
{
Dog d = new Dog("白");
d.Jiao();
d.Say();
Cat c = new Cat("灰");
c.Jiao();
Duotai dt = new Duotai("多态");
dt.Jiao();
Console.ReadLine();
}
}
///
/// 父类
///
class Animal
{
public Animal(string type, string color)
{
this.Type = type;
this.Color = color;
}
public string Type { get; set; }
public string Color { get; set; }
///
/// 多态(就是重写):父类的虚方法,关键字virtual,定义是为了被子类所重写,子类可以不重写默认会执行父类的虚方法。重写了以后就按子类的来调用
///
public virtual void Jiao()
{
Console.WriteLine("这个是父类的虚方法,重写时关键字virtual改为override后只能改方法体代码,其他如(访问修饰符,返回值类型,方法名,参数列表..)都不允许修改。");
}
public void Say() { Console.WriteLine("这是父类的一个普通方法,了解关键字new在父类中的隐藏成员作用"); }
}
///
/// 狗类
///
class Dog : Animal
{
//给父类构造函数传参,base关键字
public Dog(string color)
: base("狗", color) //base关键字不能在静态方法中使用,作用:调用基类的构造函数,还可以base.父类成员名()来访问
{
}
///
/// 重写父类的叫方法
///
public override void Jiao()
{
Console.WriteLine("一条{0}色的{1}在 汪汪汪 的叫", Color, Type);//只要继承了就可以使用父类成员 Color, Type。
}
public new void Say() { Console.WriteLine("子类成员与父类成员同名,调用时默认是父类成员,如果想调用子成员需要关键字new才能调用子类"); }
}
///
/// 猫类
///
class Cat : Animal
{
public Cat(string color)
: base("猫", color)//base关键字不能在静态方法中使用,作用:调用基类的构造函数,还可以base.父类成员名()来访问
{
}
///
/// 重写父类的叫方法
///
public override void Jiao()
{
Console.WriteLine("一条{0}色的{1}在 喵喵喵 叫", Color, Type);
}
}
///
/// 多态
///
class Duotai : Animal
{
//用户在程序中会遇到 this 和 base 关键字,this 关键字代表的是当前类的对象,而 base 关键字代表的是父类中的对象。用法是一样的
public Duotai(string color)
: base("多态", color) //base关键字不能在静态方法中使用,作用:调用基类的构造函数,还可以base.父类成员名()来访问
{
}
}
}
自己做的笔记: