java面向对象编程的基础原理“ 玉不琢,不成器;人不学,不知道。”
面向对象编程的三大特性分别是封装、继承、多态。c#、java属于面向对象语言。下面将帮助大家更深一步了解并运用这三大特性。
01
—
封 装
封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。
一个 访问修饰符 定义了一个类成员的范围和可见性。
- public:所有对象都可以访问;
- private:对象本身在对象内部可以访问;
- protected:只有该类对象及其子类对象可以访问
- internal:同一个程序集的对象可以访问;
- protected internal:访问限于当前程序集或派生自包含类的类型。
class Program
{
static void Main(string[] args)
{
Rectangle r = new Rectangle(30,10);
r.Display();
Console.Read();
}
}
class Rectangle
{
//成员变量声明为private
private double length;
private double width;
public Rectangle(double len,double wid) {
length = len;
width = wid;
}
public double GetArea(){
return length * width;
}
public void Display()
{
Console.WriteLine("长度:{0}", length);
Console.WriteLine("宽度:{0}", width);
Console.WriteLine("面积:{0}", GetArea());
}
}
运行结果如下:
02
—
继 承
并非所有基类成员都可供派生类继承。 以下成员无法继承:
- 静态构造函数:用于初始化类的静态数据。
- 实例构造函数:在创建类的新实例时调用。 每个类都必须定义自己的构造函数。
- 终结器:由运行时的垃圾回收器调用,用于销毁类实例。
- 只有在基类中嵌套的派生类中,私有成员才可见。 否则,此类成员在派生类中不可见。 在以下示例中,A.B 是派生自 A 的嵌套类,而 C 则派生自 A。 私有 A.value 字段在 A.B 中可见。 不过,如果从 C.GetValue 方法中删除注释并尝试编译示例,则会生成编译器错误 CS0122:“'A.value' 不可访问,因为它具有一定的保护级别。”
public class A
{
private int value = 10;
public class B : A
{
public int GetValue()
{
return this.value;
}
}
}
public class C : A
{
// public int GetValue()
// {
// return this.value;
// }
}
public class Example
{
public static void Main(string[] args)
{
var b = new A.B();
Console.WriteLine(b.GetValue());
}
}
// The example displays the following output:
// 10
- 受保护成员仅在派生类中可见。
- 内部成员仅在与基类同属一个程序集的派生类中可见, 在与基类属于不同程序集的派生类中不可见。
- 公共成员在派生类中可见,并且属于派生类的公共接口。 可以调用继承的公共成员,就像它们是在派生类中定义一样。 在以下示例中,类 A 定义 Method1 方法,类 B 继承自类 A。 然后,以下示例调用 Method1,就像它是 B 中的实例方法一样。
public class A
{
public void Method1()
{
// Method implementation.
}
}
public class B : A
{ }
public class Example
{
public static void Main()
{
B b = new B();
b.Method1();
}
}
派生类还可以通过提供重写实现代码来重写继承的成员。 基类成员必须标记有 virtual 关键字,才能重写继承的成员。 默认情况下,基类成员没有 virtual 标记,因此无法被重写。 如果尝试重写非虚成员(如以下示例所示),则会生成编译器错误 CS0506:“<member> 无法重写继承的成员 <member>,因为继承的成员没有 virtual、abstract 或 override 标记。”
public class A
{
public virtual void Method1()
{
// Do something.
}
}
public class B : A
{
public override void Method1() // Generates CS0506.
{
// Do something else.
}
}
在某些情况下,派生类必须重写基类实现代码。 标记有 abstract 关键字的基类成员要求派生类必须重写它们。 如果尝试编译以下示例,则会生成编译器错误 CS0534:“<class> 不实现继承的抽象成员 <member>”,因为类 B 没有提供 A.Method1 的实现代码。
public abstract class A
{
public abstract void Method1();
}
public class B : A // Generates CS0534.
{
public void Method3()
{
// Do something.
}
}
继承仅适用于类和接口。 其他各种类型(结构、委托和枚举)均不支持继承。 因为这些规则的存在,如果尝试编译以下代码,则会生成编译器错误 CS0527:“接口列表中的类型“ValueType”不是接口。” 此错误消息指明,尽管可以定义结构实现的接口,但不支持继承。
public struct ValueStructure : ValueType // Generates CS0527.
{
}
03
—
多 态
同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。换句话说,实际上就是同一个类型的实例调用"相同"的方法,产生的结果是不同的。这里的"相同"打上双引号是因为这里的相同的方法仅仅是看上去相同的方法,实际上它们调用的方法是不同的。
1、重载(overload): 在同一个作用域(一般指一个类)的两个或多个方法函数名相同,参数列表不同的方法叫做重载,它们有三个特点(俗称两必须一可以):
- 方法名必须相同
- 参数列表必须不相同
- 返回值类型可以不相同
例如:
public void Sleep()
{
Console.WriteLine("小红睡觉!");
}
public void Sleep(int time)
{
Console.WriteLine("小红,{0}点睡觉!", time);
}
public string Sleep(int time)
{
Console.WriteLine("小红,{0}点睡觉!", time);
return "收到!";
}
3 重写
- 相同的方法名
- 相同的参数列表
- 相同的返回值
public virtual void EatFood(){
Console.WriteLine("小红吃东西!");
}
派生类(子类)中的定义:
public override void EatFood(){
Console.WriteLine("小华吃东西!");
//base.EatFood();
}
小提示:经常有童鞋问重载和重写的区别,而且网络上把这两个的区别作为 C# 做常考的面试题之一。实际上这两个概念完全没有关系,仅仅都带有一个"重"字。他们没有在一起比较的意义,仅仅分辨它们不同的定义就好了。
class Peonle
{
public virtual void EatFood(){
Console.WriteLine("小红吃东西");
}
}
注意:虚方法也可以被直接调用。如:
Peonle p = new Peonle();
p.EatFood();
执行输出结果为:
5
抽象方法
public abstract class People
{
public abstract void Live();
}
public class Man: People
{
public override void Live()
{
Console.WriteLine("Man重写的抽象方法");
//throw new NotImplementedException();
}
}
注意:抽象方法只能在抽象类中定义,如果不在抽象类中定义,则会报出如下错误:
虚方法和抽象方法的区别是:因为抽象类无法实例化,所以抽象方法没有办法被调用,也就是说抽象方法永远不可能被实现。
public void Sleep(){
Console.WriteLine("Animal Sleep");
}
则在派生类 Cat 中定义隐藏方法的代码为:
new public void Sleep(){
Console.WriteLine("Cat Sleep");
}
或者为:
public new void Sleep()
{
Console.WriteLine("Cat Sleep");
}
隐藏主要用在无法改变父类方法的情况下,一般不去使用隐藏方法,
因为很容易引起方法调用的混乱。
隐藏和重写的区别:
隐藏:只是将父类中的方法给隐藏了,实际这个方法还存在。
重写:将原先父类中的方法完全重写了,原先的方法是不存的了。
class Program
{
static void Main(string[] args)
{
People people = new Man();
people.Live();
people.Eat();
Man man = new Man();
man.Live();
man.Eat();
Console.Read();
}
}
public class People
{
public void Live()
{
Console.WriteLine("People:北京");
}
public virtual void Eat()
{
Console.WriteLine("People:香蕉");
}
}
public class Man : People
{
new public virtual void Live()
{
Console.WriteLine("Man:上海");
}
public override void Eat()
{
Console.WriteLine("Man:苹果");
}
}
下篇更精彩
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/25570.html