using
System;
using
System.Text;
namespace
ReferenceType
{
class
Program
{
static
void
Main(
string
[] args)
{
//引用类型 在内存的栈上面只存储一个引用,在内存的堆上面才会存储具体的值
//object, string, dynamic他们都是别名,分别对应System.Object, System.String, System.Dynamic
//class
//C#运行分为两阶段:编译阶段、运行阶段,通常的类型检查都在编译阶段,而dynamic的类型检查在运行阶段。
Console
.WriteLine(
"\nobject引用类型示例:"
);
object
o =
new
object
();
//Object o2 = new Object();//在这里看起来不区分大小写,实际上大写的代表了System.Object,由于引用了System,所以这里省略了System.
Console
.WriteLine(
"o的类型: "
+ o.GetType());
//获取类型
Console
.WriteLine(
"o转换为字符串: "
+ o.ToString());
//转为字符串,object作为基类,这里只输出了o的类型,没有做处理
int
i = 5;
Console
.WriteLine(
"int i = 5;\ni转换为字符串: "
+ i.ToString());
//而int等其他的类型,ToString()方法会返回变量真实的值,而不是返回类型。
Console
.WriteLine(
"\nstring引用类型示例:"
);
string
s =
"CrazyBun"
;
string
s2 =
"Crazy"
;
s2 +=
"Bun"
;
Console
.WriteLine(
"s = "
+ s);
Console
.WriteLine(
"s2= "
+ s2);
//字符串相加
Console
.WriteLine(
"字符串s与s2的值是否相等? "
+ (s == s2).ToString() +
" (这里只判断值,但他们在内存中的位置是不一样的)"
);
Console
.WriteLine(
"字符串s与s2是否完全相等? "
+ ((
object
)s == (
object
)s2).ToString() +
" (包括引用位置)"
);
char
c = s[2];
Console
.WriteLine(
"s中第三个字符是: "
+ c);
string
u =
"\\\u0066\n"
;
//字符串也可以存入Unicode码
//“\\”转义字符,会输出“\”,u0066为“f”的Unicode码,“\n”也是转义字符,输出回车
Console
.WriteLine(
"转义字符和Unicode: "
+ u);
string
at =
@"E:\Visual Studio 2015\Projects\HelloWord\HelloWord\Program.cs"
;
//字符串前面加上@,则字符串中的“\”就不会变成转义字符
Console
.WriteLine(
" at: "
+ at);
string
noAt =
"E:\\Visual Studio 2015\\Projects\\HelloWord\\HelloWord\\Program.cs"
;
//如果不加上@,就需要使用转义字符
Console
.WriteLine(
"noAt: "
+ noAt);
Console
.WriteLine(
"字符串长度at: "
+ at.Length);
Console
.WriteLine(
"at中是否包含\"2015\": "
+ at.Contains(
"2015"
));
Console
.WriteLine(
"\"2015\"第一次出现的位置: "
+ at.IndexOf(
"2015"
));
//(从0开始)
Console
.WriteLine(
"\n字符串每次赋值的时候,都会重新分配内存空间,会很耗费资源,所以如果一个字符串需要经常操作的话要用StringBuilder"
);
StringBuilder
builder =
new
StringBuilder
();
//定义一个长度不固定的字符串
builder.Append(
"builder:"
);
builder.Append(
"Crazy"
);
builder.Append(
"Bun"
);
Console
.WriteLine(builder);
builder.AppendFormat(
"\nFormat: {0} {1} {2}"
,
"Hello!"
,
"CrazyBun,"
,
"I Love U!"
);
//格式化String,用{0}表示后面第0个参数
Console
.WriteLine(builder);
var
person =
new
Person
(
"CrazyBun"
, 24);
Console
.WriteLine(
"\nclass引用类型示例:"
);
Console
.WriteLine(
"Name:"
+ person.getName());
//Alt+→获得语法提示
Console
.WriteLine(
"Age:"
+ person.getAge());
Console
.WriteLine(
"static Gender:"
+
Person
.getStaticGender());
//静态方法是直接通过类调用的
Console
.WriteLine(
"静态的成员变量或方法都是存储在类上面的,而不是存储在实例化的某个变量上,所以不能通过实例化的变量调用"
);
Console
.WriteLine(
"Name属性:"
+ person.Name +
"(默认值)"
);
Console
.WriteLine(
"Age属性:"
+ person.Age +
"(默认值)"
);
person.Name =
"CrazyBun"
;
person.Age = 24;
//这里调用了Age属性的set
Console
.WriteLine(
"Name属性:"
+ person.Name +
"(赋值后)"
);
//调用了Age属性的get
Console
.WriteLine(
"Age属性:"
+ person.Age +
"(赋值后)"
);
//调用了Age属性的get
Console
.WriteLine(
"class中属性的优势是比方法更方便,安全性更灵活"
);
Console
.WriteLine(
"\nInterface引用类型示例:"
);
Console
.WriteLine(
"接口方法getSuper():"
+ person.getSuper());
Console
.WriteLine(
"抽象类中的变量gender:"
+ person.gender);
Console
.WriteLine(
"抽象类中的抽象方法getAbstractGender():"
+ person.getAbstractGender());
Console
.ReadLine();
}
}
//继承只能继承一个类,但是可以继承多个接口。
class
Person
:
Man
,
ISuper
//定义class时如果不写访问修饰符,则默认为internal,仅在命名空间内可用
{
string
name;
int
age;
/*每一个class中都有一个构造函数,如果不写够早函数,则默认为:
public Person()
{
}*/
public
Person(
string
myName,
int
myAge)
{
this
.name = myName;
this
.age = myAge;
}
/*class内部的变量或方法,如果不写访问修饰符,则默认为private,只能在class内部访问
为了可以在Main方法中使用,所以需要设置访问修饰符为public*/
public
string
getName()
{
return
name;
}
public
int
getAge()
{
return
age;
}
public
static
string
getStaticGender()
//static为静态方法或变量
{
return
"男"
;
}
// 定义一个Name属性方法,与name不同
public
string
Name
{
//默认为public
get
;
//get可以使该属性被取到
set
;
//set可以使该属性能够被赋值
}
// 定义一个Age属性方法,与age不同
public
int
Age
{
//也可以在get中做一些处理,注意这里没有“;”了
get
{
return
age + 10;
}
set
{
age =
value
- 10;
//value是该属性被赋的值
}
}
//Ctrl + Shift + B 编译
public
int
getSuper()
//继承了接口的话必须要实现它的方法
{
return
age + 100;
}
public
override
string
getAbstract()
//继承了抽象类的话也必须要实现它的方法,记得加上override
{
return
"实现抽象方法"
;
}
}
/*Interface只能在里面包含方法、属性、索引和事件,class还可以包含成员变量和构造函数等等
interface具体的实现需要在继承的class里实现
*/
interface
ISuper
{
int
getSuper();
}
/*Interface 与 abstract类的区别:
abstract类是不能被实例化的(意思就是无法Man man = new Man()),而是由其他类来继承抽象类,在继承的类中实现该方法*/
abstract
class
Man
{
public
string
gender =
"男"
;
public
string
getAbstractGender()
{
return
gender;
}
public
abstract
string
getAbstract();
}
/*接口是一个引用类型,相当于规则,里面只能有方法、属性、索引和事件,不能有成员变量。一个类可以继承多个接口,并且必须要实现接口里所有的方法。
抽象类依然是一个类,它不但有抽象的方法,也可以有一些不抽象的方法,不能被实例化,可以包含字段、成员变量、抽象方法、非抽象方法。
一个类继承了该抽象类之后,只需要它的实现抽象方法,其他的非抽象方法、成员变量都是可以直接得到继承的。*/
}
执行结果
![](https://i-blog.csdnimg.cn/blog_migrate/6e9af04e8ae289f0373ff140f8842231.png)