C#面向对象基础02
对象的引用
对象的引用的传递,对于引用类型而言,它并不是值的复制而是对象都指向了同一个引用类型,因此对被指向的引用类型改变会影响所有的指向该引用的对象。(传递给函数也是给引用传递的)
代码语言:javascript复制using System;
namespace day06test01
{
class Program
{
/// <summary>
/// 对象的引用
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
//值之间拷贝,复制传递。对于值类型来讲,它只是实现值的复制改变原来的值不会影响后面的值
int a = 10;
int b = a;
a ;
Console.WriteLine(b);
//对象的引用的传递,对于引用类型而言,它并不是值的复制而是对象都指向了同一个引用类型,因此对被指向的引用类型改变会影响所有的指向该引用的对象
Test t1 = new Test(12);
Test t2 = t1;
t1.Age ;
Console.WriteLine(t2.Age);
Console.WriteLine("Hello World!");
}
}
class Test
{
public int Age
{
set;
get;
}
public Test(int Age)
{
this.Age = Age;
}
}
}
构造函数
用来创建对象,并且可以在构造函数中对对象初始化。当然,可以有多个构造函数形成重载。根据传进的参数不同可以进行不同的初始化。
代码语言:javascript复制using System;
namespace day06test02
{
class Program
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Test t0 = new Test();
Test t1 = new Test(12);
Test t21 = new Test("ss", 12);
Console.WriteLine(t0.Name);
Console.WriteLine(t0.Num);
Console.WriteLine(t1.Name);
Console.WriteLine(t1.Num);
Console.WriteLine(t21.Name);
Console.WriteLine(t21.Num);
Console.WriteLine("Hello World!");
}
}
class Test
{
public int Num { set; get; }
public String Name { set; get; }
public Test()
{
this.Name = "1";
this.Num = 4;
}
public Test(int num)
{
this.Num = num;
}
public Test(String str, int num)
{
this.Name = str;
this.Num = num;
}
}
}
继承
通过继承可实现代码的复用,(Object是所有的类的基类)。继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类,这使得创建和维护应用程序变得更容易。同时也有利于重用代码和节省开发时间。
当创建一个类时,程序员不需要完全重新编写新的数据成员和成员函数,只需要设计一个新的类,继承了已有的类的成员即可。这个已有的类被称为的基类,这个新的类被称为派生类。
继承的思想实现了 属于(IS-A) 关系。例如,哺乳动物 属于(IS-A) 动物,狗 属于(IS-A) 哺乳动物,因此狗 属于(IS-A) 动物。
基类的初始化
派生类继承了基类的成员变量和成员方法。因此父类对象应在子类对象创建之前被创建。您可以在成员初始化列表中进行父类的初始化。
下面的程序演示了这点:
代码语言:javascript复制using System;
namespace RectangleApplication
{
class Rectangle
{
// 成员变量
protected double length;
protected double width;
public Rectangle(double l, double w)
{
length = l;
width = w;
}
public double GetArea()
{
return length * width;
}
public void Display()
{
Console.WriteLine("长度: {0}", length);
Console.WriteLine("宽度: {0}", width);
Console.WriteLine("面积: {0}", GetArea());
}
}//end class Rectangle
class Tabletop : Rectangle
{
private double cost;
public Tabletop(double l, double w) : base(l, w)
{ }
public double GetCost()
{
double cost;
cost = GetArea() * 70;
return cost;
}
public void Display()
{
base.Display();
Console.WriteLine("成本: {0}", GetCost());
}
}
class ExecuteRectangle
{
static void Main(string[] args)
{
Tabletop t = new Tabletop(4.5, 7.5);
t.Display();
Console.ReadLine();
}
}
}
C# 多重继承
多重继承指的是一个类别可以同时从多于一个父类继承行为与特征的功能。与单一继承相对,单一继承指一个类别只可以继承自一个父类。
C# 不支持多重继承。但是,您可以使用接口来实现多重继承。下面的程序演示了这点:
代码语言:javascript复制using System;
namespace InheritanceApplication
{
class Shape
{
public void setWidth(int w)
{
width = w;
}
public void setHeight(int h)
{
height = h;
}
protected int width;
protected int height;
}
// 基类 PaintCost
public interface PaintCost
{
int getCost(int area);
}
// 派生类
class Rectangle : Shape, PaintCost
{
public int getArea()
{
return (width * height);
}
public int getCost(int area)
{
return area * 70;
}
}
class RectangleTester
{
static void Main(string[] args)
{
Rectangle Rect = new Rectangle();
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
// 打印对象的面积
Console.WriteLine("总面积: {0}", Rect.getArea());
Console.WriteLine("油漆总成本: ${0}" , Rect.getCost(area));
Console.ReadKey();
}
}
}
尝试练习:
代码语言:javascript复制using System;
namespace day06test03
{
class Program
{
/// <summary>
/// 继承
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "man";
p1.Num = 22;
p1.SayHello();
Console.WriteLine("Hello World!");
Cman m1 = new Cman();
m1.Name = "qqq";
m1.Num = 23;
m1.SayHello();
m1.KunFu();
Hman h1 = new Hman();
h1.SayHello();
h1.Name = "hhh";
h1.Num = 666;
h1.paocai();
Person p2 = m1;
Person p3 = h1;
Cman zgr = (Cman)p2; //在对象前加类型名,保证要指向的类型是所需的
zgr.KunFu();
Cman zgr2 = (Cman)p3; //抛出异常,不能将一个Hman对象 让 Cman类型的对象 来指向
zgr2.SayHello();
}
}
class Person
{
public String Name { set; get; }
public int Num { set; get; }
public void SayHello()
{
Console.WriteLine("good! {0}", this.Name);
}
}
class Cman : Person
{
public String DiZhi { set; get; }
public void KunFu()
{
Console.WriteLine("{0} Chinesse have KunFu", this.Name);
}
}
class Hman : Person
{
public String Eating { set; get; }
public void paocai()
{
Console.WriteLine("{0} 韩国人 做泡菜", this.Name);
}
}
}
异常
异常是在程序执行期间出现的问题。C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。
异常提供了一种把程序控制权从某个部分转移到另一个部分的方式。C# 异常处理时建立在四个关键词之上的:try、catch、finally 和 throw。
- try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块。
- catch:程序通过异常处理程序捕获异常。catch 关键字表示异常的捕获。
- finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行。例如,如果您打开一个文件,不管是否出现异常文件都要被关闭。
- throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。
练习:
代码语言:javascript复制using System;
namespace day06test04
{
class Program
{
/// <summary>
/// 异常
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
try
{
int a = 5;
int b = a / 2;
Console.WriteLine(b);
throw new Exception("666666!"); //throw 抛出异常
}
catch (Exception e) //catch 捕获异常
{
Console.WriteLine(e.Message); //并且打印
}
Console.WriteLine("Hello World!");
}
}
}
常量和静态成员
常量(一定不会改变的量,才需要声明为常量),常量是固定值,程序执行期间不会改变。常量可以是任何基本数据类型,比如整数常量、浮点常量、字符常量或者字符串常量,还有枚举常量。
常量可以被当作常规的变量,只是它们的值在定义后不能被修改。
常量是使用 const 关键字来定义的 。定义一个常量的语法如下:
代码语言:javascript复制const <data_type> <constant_name> = value;
代码语言:javascript复制using System;
namespace day06test05
{
class Program
{
/// <summary>
/// 常量
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
const int nums = 4;
Console.WriteLine(nums);
Console.WriteLine("Hello World!");
}
}
}
C# 命名空间(Namespace)
命名空间的设计目的是提供一种让一组名称与其他名称分隔开的方式。在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突。
我们举一个计算机系统中的例子,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。
代码语言:javascript复制using System;
namespace first_space
{
class namespace_cl
{
public void func()
{
Console.WriteLine("Inside first_space");
}
}
}
namespace second_space
{
class namespace_cl
{
public void func()
{
Console.WriteLine("Inside second_space");
}
}
}
class TestClass
{
static void Main(string[] args)
{
first_space.namespace_cl fc = new first_space.namespace_cl();
second_space.namespace_cl sc = new second_space.namespace_cl();
fc.func();
sc.func();
Console.ReadKey();
}
}
using 关键字
using 关键字表明程序使用的是给定命名空间中的名称。例如,我们在程序中使用 System 命名空间,其中定义了类 Console。我们可以只写:
代码语言:javascript复制Console.WriteLine ("Hello there");
我们可以写完全限定名称,如下:
代码语言:javascript复制System.Console.WriteLine("Hello there");
您也可以使用 using 命名空间指令,这样在使用的时候就不用在前面加上命名空间名称。该指令告诉编译器随后的代码使用了指定命名空间中的名称。下面的代码演示了命名空间的应用。
代码语言:javascript复制using System;
using first_space;
using second_space;
namespace first_space
{
class abc
{
public void func()
{
Console.WriteLine("Inside first_space");
}
}
}
namespace second_space
{
class efg
{
public void func()
{
Console.WriteLine("Inside second_space");
}
}
}
class TestClass
{
static void Main(string[] args)
{
abc fc = new abc();
efg sc = new efg();
fc.func();
sc.func();
Console.ReadKey();
}
}
嵌套命名空间
命名空间可以被嵌套
代码语言:javascript复制using System;
using SomeNameSpace;
using SomeNameSpace.Nested;
namespace SomeNameSpace
{
public class MyClass
{
static void Main()
{
Console.WriteLine("In SomeNameSpace");
Nested.NestedNameSpaceClass.SayHello();
}
}
// 内嵌命名空间
namespace Nested
{
public class NestedNameSpaceClass
{
public static void SayHello()
{
Console.WriteLine("In Nested");
}
}
}
}