sealed ํค์๋๋ฅผ ๋ฉ์๋์ ์ฌ์ฉ!
- ๋ถ๋ชจํด๋์ค์์ ์ค์๋์ ํ๊ฒ๋ ํ๋ ์์์ ์์ํด๋์ค์์ ๊ฑด๋๋ฆฌ๋ฉด ์๋๋ ๊ฒฝ์ฐ
- ๋ฉ์๋์
sealed ํ์ ์๋ฅผ ์ฌ์ฉํด์ ์ ํํ ์ ์๋ค.
class Parent
{
public int num;
public int count;
public Parent(int num)
{
this.num = num;
this.count = 0;
Console.WriteLine("Parent ์์ฑ์");
}
public virtual void addCount() { }
public void showInfo()
{
Console.WriteLine("Num : {0}, Count : {1}", this.num, this.count);
}
}
class Counter : Parent
{
public Counter(int num) : base(num)
{
Console.WriteLine("Counter ์์ฑ์");
}
public sealed override void addCount()
{
base.count++;
}
}
class Calculator : Counter
{
public Calculator(int num) : base(num)
{
Console.WriteLine("Calculator ์์ฑ์");
}
public void add()
{
Console.WriteLine("๋ํ๊ธฐ 1");
this.num++;
base.addCount();
}
public void sub()
{
Console.WriteLine("๋นผ๊ธฐ 1");
this.num--;
base.addCount();
}
}
class Program
{
static void Main(string[] args)
{
Parent ncc = new Calculator(10);
ncc.showInfo();
Calculator c = (Calculator)ncc;
c.add();
c.add();
c.sub();
c.sub();
c.sub();
c.showInfo();
}
}
Output
Parent ์์ฑ์
Counter ์์ฑ์
Calculator ์์ฑ์
Num : 10, Count : 0
๋ํ๊ธฐ 1
๋ํ๊ธฐ 1
๋นผ๊ธฐ 1
๋นผ๊ธฐ 1
๋นผ๊ธฐ 1
Num : 9, Count : 5
- ์ต์์ ํด๋์ค์์
virtual๋ก ์ ์๋ ๋ฉ์๋๋ฅผ ์์๋ฐ๋ ํด๋์ค์์ sealedํ์ ์์ override๋ก ์ ์ธํ๊ฒ๋๋ฉด ๊ทธ ํด๋์ค๋ฅผ ์์๋ฐ๋ ํด๋์ค์์๋ ํด๋น ๋ฉ์๋๋ฅผ ์ฌ์ ์ ํ ์ ์๋ค.
- ํ์ ํด๋์ค์์ ์ค๋ฒ๋ผ์ด๋ ํ ์ ์๋ค.
sealed ๋ฉ์๋๋ ๊ผญ override์์์๋ง ์ฌ์ฉํ ์ ์๋ค.
sealed๋ฅผ ์ฐ๋ฉด ์์์ ์ค ์ ์์ผ๋ฏ๋ก ํ์ ํด๋์ค์์ ์ฌ์ ์ ๋ถ๊ฐ๋ฅ
ํ๋ณํ
as, () => ๊ธฐ๋ณธ ์๋ฃํ์ผ๋ก ๋ณํํ์ ๊ฒฝ์ฐ์๋ ? + is
C# ๊ธฐ๋ณธ ์๋ฃํ ๋ถ๋ฅ
| ๊ตฌ๋ถ |
์ค๋ช
|
| ์ ์ ํํ |
byte, shortm int, long |
| ์ค์ ํํ |
float, double |
| ๋ฌธ์ ํํ |
char |
| ์ฐธ, ๊ฑฐ์ง ํํ |
boolean |
class Human
{
public void showInfo()
{
Console.WriteLine("Human");
}
}
class Programmer : Human
{
public void programming()
{
Console.WriteLine("๊ฐ๋ฐ์");
}
}
class Program
{
static void Main(string[] args)
{
Human human = new Programmer();
// as ์ฐ์ฐ์๋ฅผ ์ด์ฉํด ๊ธฐ๋ณธ ์๋ฃํ์ผ๋ก ํ๋ณํ
var aa = human as Programmer;
if (aa is null) return;
int? a = human as int;
var result = human is int; // false
// as ์ฐ์ฐ์๋ ์ฐธ์กฐ ํ์ ๋๋ null ํ์ฉ ํ์๊ณผ ํจ๊ป ์ฌ์ฉํด์ผ ํฉ๋๋ค. 'int'์(๋) null์ ํ์ฉํ์ง ์๋ ๊ฐ ํ์์
๋๋ค.
string? str = human as string;
// ์ฐธ์กฐ ๋ณํ, boxing ๋ณํ, unboxing ๋ณํ, ๋ํ ๋ณํ ๋๋ null ํ์ ๋ณํ์ ํตํด 'AsisEx.Human' ํ์์ 'string'(์ผ)๋ก ๋ณํํ ์ ์์ต๋๋ค.
// =>`as`์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ ๋ณํ์ ์์, ์ฐธ์กฐ ๋ณํ ๋ฐ boxing ๋ณํ์์ ํ์ฉ
int x = (int)human;
// => 'Human' ํ์์ 'int' ํ์์ผ๋ก ๋ณํํ ์ ์์ต๋๋ค.
// double y = (double)human; // => 'Human' ํ์์ 'double' ํ์์ผ๋ก ๋ณํํ ์ ์์ต๋๋ค.
// string str2 = (string)human; // => 'Human' ํ์์ 'string' ํ์์ผ๋ก ๋ณํํ ์ ์์ต๋๋ค.
Console.WriteLine(human is int);
Console.WriteLine(human is double);
Console.WriteLine(human is string);
}
}
Output
False
False
False
- ์ฐธ์กฐํ์ ๊ธฐ๋ณธ์๋ฃํ์ผ๋ก ๋ณํ์ด ๋ถ๊ฐ๋ฅํ๋ค.(as ๋ฐ ๊ฐ์ ํ๋ณํ ๋๋ค ์๋จ(
()์ฌ์ฉ)) => C# ์์ฒด์์ ๋ง๊ณ ์์
is๋ฅผ ์ฌ์ฉํ๋๊ฒ์ ํ๋ณํ์ด ์๋ bool ํ์
์ ๋ฐํ ๊ฐ์ ํตํด ์ฒดํฌ๋ฅผ ํ๋๊ฒ์ด๊ธฐ์ ์ฌ์ฉ๊ฐ๋ฅ
- string์ ๊ฒฝ์ฐ ์ฐธ์กฐํ์ด์ง๋ง ๊ธฐ๋ณธ์๋ฃํ์ฒ๋ผ C#์์ ๋ง๊ณ ์๋๋ฏํจ.
์ด๊ธฐํ๋ ๊ฐ์ฒด์ ์ด๊ธฐํ๋์ง ์์ ๊ฐ์ฒด๋ฅผ ์์์ ๋ฉ์๋์ ๋งค๊ฐ๋ณ์๋ก ๋๊ฒผ์ ๋ ๋์ํ์ธ
class MyField
{
public int field1;
public int field2;
}
class AssignRefType
{
static void Main(string[] args)
{
MyField? mf1 = null;
MyField mf2 = new MyField() { field1 = 1, field2 = 2 };
Test(mf1);
Test(mf2);
//Console.WriteLine("mf1 => field1 : {0} field2 : {1} ", mf1.field1, mf1.field2); => error
//Console.WriteLine("mf2 => field1 : {0} field2 : {1} ", mf2.field1, mf2.field2);
TestRef(ref mf1);
TestRef(ref mf2);
Console.WriteLine("mf1 => field1 : {0} field2 : {1} ", mf1.field1, mf1.field2);
Console.WriteLine("mf2 => field1 : {0} field2 : {1} ", mf2.field1, mf2.field2);
}
private static void Test(MyField param)
{
if (param is null) param = new MyField();
param.field1 = 3;
param.field2 = 4;
}
private static void TestRef(ref MyField param)
{
if (param is null) param = new MyField();
param.field1 = 3;
param.field2 = 4;
}
}
Output
mf1 => field1 : 3 field2 : 4
mf2 => field1 : 3 field2 : 4
mf1์ ๊ฒฝ์ฐ stack๋ฉ๋ชจ๋ฆฌ์์ null์ ๊ฐ์ง๊ณ heap์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ ๋น๋์ด์์ง ์๋ค. C#์ ๊ธฐ๋ณธ์ ์ผ๋ก Call by Value์ด๊ธฐ ๋๋ฌธ์ null์ ๋ฉ์๋๋ก ๋๊ฒจ์ฃผ๊ฒ ๋๊ณ ์ง์ญ์ธ์คํด์ค๋ก ํ์ฉ๋๋ param์ด ๋ด๋ถ์์๋ง ๋ก์ง์ ์ํํ๊ณ ํ์ ์ธ์คํด์ค๊ฐ ์ญ์ ๋๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ตญ mf1์ ๊ทธ๋๋ก null์ ๊ฐ์ง๊ฒ ๋๋ค.
๋คํ์ฑ ํ์ธ ์์ ์ถ๊ฐ
class A{
public virtual void Print1()
{
Console.WriteLine("A : Print1");
}
public void Print2()
{
Console.WriteLine("A : Print2");
}
}
class A1 : A
{
public override void Print1()
{
Console.WriteLine("A1 : Print1");
}
public void Print2()
{
Console.WriteLine("A1 : Print2");
}
}
class A2 : A
{
public override void Print1()
{
Console.WriteLine("A2 : Print1");
}
public void Print2()
{
Console.WriteLine("A2 : Print2");
}
}
class A3 : A
{
public override void Print1()
{
Console.WriteLine("A3 : Print1");
}
public void Print2()
{
Console.WriteLine("A3 : Print2");
}
}
class App
{
static void Main(string[] args)
{
A[] arr = new A[]
{
new A1(),
new A2(),
new A3()
};
foreach (var a in arr)
{
a.Print1();
a.Print2();
}
}
}
Output
A1 : Print1
A : Print2
A2 : Print1
A : Print2
A3 : Print1
A : Print2
- A์ ์๋ฃํ์ผ๋ก A1, A2, A3 ์ธ์คํด์ค๋ฅผ ์์ฑํ์๋ A์์๋ ์์ ํด๋์ค์ ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ ์ ์์ผ๋, override ํค์๋๋ฅผ ์ด์ฉํด์ ์ฌ์ ์ ๋ ๋ฉ์๋์ ๊ฒฝ์ฐ ์์๋ฉ์๋์ ๊ฒฐ๊ณผ๋ก ์ถ๋ ฅ์ด ๋๋ค.
- ์ฆ override์ ์ํด ์ฌ์ ์๋ ๋ฉ์๋๋ ๋ถ๋ชจํด๋์คํ์ ์ธ์คํด์ค๋ฅผ ์์ํด๋์คํ์ ์ธ์คํด์ค๋ก ์ ์ธํ์๋ ์ฌ์ ์๋ ํํ๋ก ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
struct์ ํฌ๊ธฐ๊ฐ ์ผ์ ํฌ๊ธฐ๋ฅผ ๋์ด๊ฐ๋ฉด value type์ด ์๋ ref type => Stack Overflow
๋ฉ๋ชจ๋ฆฌ์ ์ฝ์ ํด๋์ค, ์๋๋ ๊ตฌ์กฐ์ฒด
- ์ธ์คํด์คํ๋ค๋ฉด ๊ฐ๋น์ง ์ปฌ๋ ์
(์๋)
- ๊ตฌ์กฐ์ฒด๋ ์คํ์ ๋ฐ๋ก ํ ๋น๋๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์ง์ปฌ๋ ์
์ด ๋ฐ์ ํ์ง ์์
- ํด๋์ค๋ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋ ๋ง๋ค ํ์ ๋ฉ๋ชจ๋ฆฌ ํ ๋นํ๊ธฐ ๋๋ฌธ์ ๊ฐ์ ํ๊ธฐํ๊ธฐ ์ํด์๋ ๊ฐ๋ฐ์ง์ปฌ๋ ์
์ด ํ์.
- ๋ง์ ์์ ๋ณ์๋ฅผ ๊ฐ์ง๊ณ ์๋ ๊ตฌ์กฐ์ฒด๋ NO(๋ฉ๋ชจ๋ฆฌ)
- ์ฐธ์กฐํ์์ธ ํด๋์ค๋ ๊ฐ๋ค์ ๊ฐ๋ฆฌํค๋ ์ฃผ์๋ง ์คํ์ ์ ์ฅํ์ง๋ง ๊ตฌ์กฐ์ฒด๋ ๊ฐ์ง๊ณ ์๋ ๋ณ์๋ค์ ๊ฐ๋ค์ ๋ชจ๋ ์คํ์ ์ ์ฅํ๊ธฐ ๋๋ฌธ์ ๊ทธ ํฌ๊ธฐ๋งํผ ์คํ์ ์์น ์ญ์ ์ปค์ง๊ฒ ๋จ. ํ์ง๋ง ์คํ์ ํฌ๊ธฐ๊ฐ ์ ํ์ ์ด๊ธฐ ๋๋ฌธ์ ๋๋ฌด ๋ง์ ์์ ๊ฐ์ง๊ฒ ๋๋ฉด ์คํ ์ค๋ฒํ๋ก์ฐ๊ฐ ๋ฐ์ํ ์ ์๋ ์ํ์ด ์๋ค. => ํ๋ฉ๋ชจ๋ฆฌ ์นจ๋ฒ
- ๊ตฌ์กฐ์ฒด๋ ์ธ์ ์ฌ์ฉํ ๊น?
- ๋ณ์์ ํฌ๊ธฐ๊ฐ ์๊ฑฐ๋, ์๋ช
์ด ์งง๊ณ , ์์ฃผ ํ ๋น๋๋ ๊ฐ์ฒด๋ ๊ตฌ์กฐ์ฒด๋ก ๋ง๋ค์ด ์ฃผ๋๊ฒ ์ข์.