Your SlideShare is downloading. ×
Sw203 Lecture11 Casting
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Sw203 Lecture11 Casting

2,018
views

Published on

төрөл хувиргалт

төрөл хувиргалт


1 Comment
4 Likes
Statistics
Notes
No Downloads
Views
Total Views
2,018
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
1
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Объект хандлагат програмчлалын хэл Java Хичээл : C S203 Багш : Д.Энхжаргал Төрөл хувиргалт: автомат ба механик төрөл хувиргалт Mongolia University of Science & Technology
  • 2. Java хэлний өгөгдлийн үндсэн төрлүүд
  • 3.
    • Аливаа програмчлалын хэлний хувьд төрөл хувиргалтын асуудал яригддаг. Иймд ямар нэг програмчлалын хэл дээр амжилттай програм бичихийн тулд тухайн хэлний төрөл хувиргах зарчмын талаар тодорхой ойлголттой байх нь чухал.
    • Java компилятор нь төрлүүдийг хооронд нь хөрвүүлэх дараах 2 хэлбэрээр хангагдсан. Үүнд:
        • Автоматаар (Automathic) : Хэрэв тухайн 2 төрөл нэг бүлэгт багтаж байвал тэдгээрийг хоорондоо нийцтэй төрлүүд (compatible types) гэж үзээд Java компилятор нь түүнийг автоматаар хөрвүүлдэг.
        • Гар аргаар (Manual) : Хэрэв тухайн 2 төрөл хоорондоо нийцгүй (incompatible) байвал төрлийг автоматаар хөрвүүлэх боломжгүй тул хөрвүүлэлтийг гар аргаар ( төрөл хувиргалт /type cast/- ыг ) хийх шаардлагатай. Мөн нийцтэй төрлүүдийн зарим онцгой тохиолдолд мөн төрөл хувиргалтыг гүйцэтгэнэ.
    Java хэлний Төрөл хөрвүүлэх зарчим
  • 4.
    • Java хэлэнд дараах 2 хэлбэрийн өгөгдлийг тодорхойлж ашигладаг болохыг бид мэднэ. Үүнд :
      • Primitive data type энгийн буюу Өгөгдлийн Үндсэн Төрөл ( ӨҮТ )
      • Тайлбар : Java хэлний ӨҮТ-д byte, short, int, long, char, float, double болон boolean гэсэн найман үндсэн төрөл багтдаг. Эдгээр энгийн буюу үндсэн өгөгдлийн төрлүүд нь дан хувьсагчийг тодорхойлдог. Өгөгдлийн бүх төрлүүд нь ашиглаж байгаа битээсээ хамааран тодорхой интервалд утга нь хэлбэлздэг.
      • Object reference data type заалт буюу Өгөгдлийн Хийсвэр Төрөл ( ӨХТ )
      • Тайлбар: Java хэл нь объект хандлагат програмчлалын хэл учраас түүнд class, interface гэх мэтийн үүссэн буюу ӨХТ-үүдийг өргөн ашигладаг.
    • Иймд төрлийн хөрвүүлэлтийн тухай авч үзэхийн тулд бид дараах 4 хэлбэрийг ярих шаардлагатай. Үүнд:
        • ӨҮТ-ийг хөрвүүлэх (conversion)
        • ӨҮТ-ийг хувиргах (casting)
        • Ө X Т-ийг хөрвүүлэх (conversion)
        • Ө X Т-ийг хувиргах (casting)
    Java хэлний өгөгдлийн төрлүүд ( Үндсэн ойлголт сэргээх нь )
  • 5. ӨҮТ-ийн хөрвүүлэлт (Conversion of primitives )
    • ӨҮТ-ийн хувьд хөрвүүлэлт хийхдээ дараах 3 тохиолдлыг авч үзнэ. Үүнд:
        • Утга олголт (Assignment)
        • Функц дуудалт (Method call)
        • Арифметик үйлдэл (Arithmetic promotion)
    • ӨҮТ-ийн хувьд хийгдэх аливаа төрөл хөрвүүлэлт нь компиляцын үед хийгддэг. Учир нь компиляцын үед тухайн төрөл хөрвүүлэлтийг дүрмийн дагуу эсвэл дүрэм зөрчсөн эсэхийг тогтоох бөгөөд хэрэв дүрмийн дагуу зөв хийгдээгүй бол алдааны мэдээлэл өгнө.
    • Санамж: Булийн төрлөөс бусад төрөл рүү, бусад төрлөөс булийн төрөл рүү хөрвүүлэлт хэзээ ч хийгдэхгүй
  • 6. Энгийн төрлийн хөрвүүлэлт: Утга олголт
    • Одоо Утга олголт (Assignment) -ийг авч үзье.
      • Жишээ 1:
          • i nt i;
          • double d;
          • i=10;
          • d=i;
    • Дээрх жишээний d=i; гэсэн мөрөнд i гэсэн int хувьсагчийн утгыг double төрлийн d хувьсагчид олгож байна. int төрлийн өргөн нь double төрлийн өргөнөөс ихгүй тул Java компилятор int төрлийг double төрөл рүү автоматаар хөрвүүлнэ.
      • Жишээ 2:
          • double d;
          • short s;
          • d=1.2345;
          • s=d;
    • Дээрх жишээний s= d; гэсэн мөрөнд d гэсэн double хувьсагчийн утгыг short төрлийн s хувьсагчид олгож байна. double төрлийн өргөн нь short төрлийн өргөнөөс их тул Java компилятор алдаа заана.
  • 7.
    • ӨҮТ-ийн хувьд утга олгох үед хөрвүүлэлт хийхдээ дараах дүрмийг баримтална.
      • Буллийн хувьсагчийн утгыг бусад төрлийн хувьсагчид оноох боломжгүй.
      • Буллийн бус хувьсагчийн утгыг өөр буллийн бус хувьсагчийн утга руу хөрвүүлэх боломжтой бол түүнийг өргөтгөсөн хөрвүүлэлт (widening conversion) гэнэ.
      • Жич: Энд утга олгох гэж буй төрлийн өргөн нь утга олгогдох гэж буй төрлийн өргөнөөс ихгүй байна
          • i nt i;
          • double d;
          • i=10;
          • d=i;
      • Буллийн бус хувьсагчийн утгыг өөр буллийн бус хувьсагчийн утга руу хөрвүүлэх боломжгүй бол явцуу хөрвүүлэлт (narrow conversion) гэнэ.
      • Жич: Энд утга олгох гэж буй төрлийн өргөн нь утга олгогдох гэж буй төрлийн өргөнөөс их байна
          • double d;
          • short s;
          • d=1.2345;
          • s=d;
    Энгийн төрлийн хөрвүүлэлт: Утга олголт Компилятор энд алдаа заана !!! double төрлийн утгыг short төрөл рүү хөрвүүлж d айна int төрлийн утгыг double төрөл рүү хөрвүүлж байна
  • 8.
    • “ Өргөтгөсөн хөрвүүлэлтийн үед утга олгох гэж буй төрлийн өргөн нь утга олгогдох гэж буй төрлийн өргөнөөс ихгүй байна” гэсэн мөрдлөгийг дэлгэрэнгүй тайлбарлъя.
    • Дээрх зурагт java хэлний өгөгдлийн үндсэн төрлүүдийг битийн хэмжээнээс нь хамааруулан зүүнээс баруун тийш жагсааж байрлуулан сумтай шугамаар холбосон байна.
    • Тухайлбал: int төрөл нь byte , short, char гэсэн 3 төрлөөс том төрөл гэсэн үг. Иймд byte, short, char төрлийн хувьсагчдыг int төрөл рүү автоматаар хөрвүүлэх боломжтой. Иймд утга олгогдох төрлийн өргөн нь эх төрлийнхөөс багагүй байх тохиолдолд хөрвүүлэлтийг автоматаар хийх боломжтой болох нь харагдаж байна.
    Энгийн төрлийн хөрвүүлэлт: Утга олголт char short byte int long float double
  • 9.
    • Эндээс дараах дүрмийг гаргаж болно.
    • Өргөтгөсөн хөрвүүлэлт (widening conversion) -ийн үед
      • byte төрлөөс short, int, long, float, double төрөл рүү
      • short төрлөөс int, long, float, double төрөл рүү
      • int төрлөөс long, float, double төрөл рүү
      • long төрлөөс float, double төрөл рүү
      • float төрлөөс double төрөл рүү тус тус автоматаар хөрвүүлэх боломжтой
    • Иймд өргөтгөсөн хөрвүүлэлт (widening conversion) -ийн үед мэдээллийн алдагдал гарахгүй гэсэн дүгнэлтэнд хүрч байна.
    Энгийн төрлийн хөрвүүлэлт: Утга олголт
  • 10.
    • Харин сумны эсрэг чиглэлд бол боломжгүй. Өх: int төрлийн хувьсагчийн byte төрөл рүү хөрвүүлвэх боломжгүй. Учир нь byte төрөл нь 1 байт, int төрөл 4 байтын хэмжээтэй тул өргөн нь бага хэмжээтэй төрөл рүү хөрвүүлэхэд зарим орон хаягдахад хүрнэ. Эндээс дээрх зурагны сумтай шугамны зүүн гар талд орших төрлийг түүний баруун гар талд орших ямар ч төрөл рүү хөрвүүлэх боломжтой. Харин эсрэгээр өгөгдлийн төрлийг түүний зүүн гар талд орших ямарч төрөл рүү хөрвүүлэх боломжгүй байдаг тул компилятор түүнийг алдаанд тооцдог. Алдааг засахыг тулд төрөл хувиргалт буюу “type casting” хийнэ.
    Энгийн төрлийн хөрвүүлэлт: Утга олголт char short byte int long float double
  • 11.
    • Эндээс дараах дүрмийг гаргаж болно.
    • Явцуу хөрвүүлэлт (narrow conversion) -ийн үед
      • byte төрлөөс char төрөл рүү
      • short төрлөөс byte, char төрөл рүү
      • char төрлөөс byte, short төрөл рүү
      • int төрлөөс byte, short, char төрөл рүү
      • long төрлөөс byte, short, char, int төрөл рүү
      • float төрлөөс byte, short, char, int, long төрөл рүү
      • double төрлөөс byte, short, char, int, long, float төрөл рүү тус тус автоматаар хөрвүүлэх боломжгүй. Учир нь мэдээллийн алдагдалд орох аюултай тул Явцуу хөрвүүлэлт (narrow conversion) -ийн үед төрөл хувиргалт (type cast) -ыг хийнэ.
    • Casting гэдэг нь нэг ёсондоо явцуу хөрвүүлэлтийн үед мэдээллийн алдагдалд орох эрсдлээс сэргийлэхийг компиляторт анхааруулж буй хэрэг юм.
    Энгийн төрлийн хөрвүүлэлт: Утга олголт
  • 12.
    • Явцуу хөрвүүлэлт (narrow conversion) –ийн жишээ
    • short s=259;
      • byte b= s; // Энд компилятор алдаа заана
      • System.out.println(“s=”+s+”, b=”+b);
    • Алдааг засахдаа төрөл хувиргах үйлдэл хийнэ.
      • short s=259;
      • byte b=(byte) s; // Төрөл хувиргалт
      • System.out.println(“b=”+b);
    • Ийнхүү төрөл хувиргалтыг хийхдээ дугуй хос хаалт ашиглана.
    • Одоо b хувьсагч ямар утга авах вэ? хэрэв s хувьсагчийн утга byte төрлийн тодорхойлогдох мужаас (256) хэтэрсэн байвал тодорхойлогдох мужийн хамгийн их утгыг модулиар жишиж авна. s хувьсагчийн утга 259 (хоёртоор 100000011) бөгөөд түүнийг 256 модулиар жишихэд 3 тул b=3; болно.
    Төрөл хувиргалт (Casting)
  • 13. Төрөл хувиргалт (Casting)
    • Эндээс харахад тоо нь хөрвөх төрлийнхөө тодорхойлогдох мужаас хэтэрвэл хөрвөх төрлийн тодорхойлогдох мужийн хамгийн их утгыг модулиар жишиж авна.
    • Харин бодит тоог бүхэл тоо руу хөрвүүлэхдээ хэрчигдсэн (transaction) хувиргалтыг хийнэ. ӨХ: бодит тоог бүхэл тоо руу хөрвүүлэхдээ түүний бутархай хэсгийг хэрчин хаяж бүхэл хэсгийг нь авч ашиглах бөгөөд уг бодит тоо нь хөрвөх төрлийнхөө тодорхойлогдох мужаас хэтэрвэл мөн л хөрвөх төрлийн тодорхойлогдох мужийн хамгийн их утгыг модулиар жишиж авна.
    Зураг: short төрлийг byte төрөлд хувиргах
  • 14. ӨҮТ-ийн хөрвүүлэлт: Функц дуудалт
    • Төрөл хөрвүүлэлтийн өөр нэг хэрэглээ бол функц дуудалт юм. Энэ нь функцыг дуудахдаа зарлагдсан төрлөөс нь өөр төрлийн аргументтай дуудах үед яригдана.
    • Дараах нөхцөлд функцыг дуудахдаа түүний аргументын төрлөөс өөр төрлийн аргументтай дуудаж болдог. Үүнд: дуудаж буй аргументын төрөл нь уул функцын аргументын төрлөөс өргөнөөрөө ихгүй байх ёстой.
    • Жишээ нь:
      • float frads=2.34567f;
      • double d;
      • d= Math.cos(frads);
      • System.out.println("d="+d);
    Math.cos() нь double төрлийн 1 аргументтай стандарт функц билээ . Энд түүнийг float төрлийн аргументтай дуудаж байна. float төрлийн өргөн double төрлийн өргөнөөс ихгүй тул төрлийг автоматаар хөрвүүлэх учраас компилятор алдаа заахгүй
  • 15. Энгийн төрлийн хөрвүүлэлт: Функц дуудалт
    • Харин функцыг дуудаж буй аргументын төрөл нь уул функцын аргументын төрлөөс өргөнөөрөө их байвал компилятор алдаа заах бөгөөд энэ тохиолдолд төрөл хувиргалт (casting) хийнэ. Жишээ:
      • class A{
      • public int inc(int i){
      • return i+1;
      • }
      • }
      • public class test2{
      • public static void main(String args[]){
      • double d=12.0;
      • int k;
      • A a= new A();
      • k=a.inc(d);
      • System.out.println("K="+k);
      • }
      • }
      • k=a.inc( (int) d); болгож өөрчлөх замаар Casting хийх
    int төрлийн 1 аргументтай double төрлийн 1 аргументтай дуудахад компилятор алдаа заана .
  • 16.
    • Төрөл хөрвүүлэлтийн өөр нэг хэрэглээ бол арифметик илэрхийлэл юм. Ямар нэг илэрхийллийн үр дүнг хувьсагчид олгох үед төрөл таарахгүй бол хувиргалт хийдэг. Үүнийг илэрхийллийн төрөл хувиргалт гэнэ.
    • Илэрхийлэлд орсон үйлдлээс хамааран гахах утгын нарийвчлал янз бүр айдаг. Жишээ нь.
          • byte a=60;
          • byte b=50;
          • byte c=100;
          • int d=a*b/c ;
    • a*b гэсэн завсрын үйлдлийн үр дүн byte төрлийн мужаас хэтэрнэ. Иймд Java хэлэнд бүх byte болон short төрлийн хувьсагчид орсон операндын үр дүнг автоматаар өргөтгөн int төрөлд хөрвүүлэн үр дүн болох 3000 гэсэн утгыг завсрын int төрлийн хувьсагчид хадгална. Ийнхүү автомат төрөл хувиргалтыг дээрх илэрхийллийн хувьд хэрэгжүүлж байна.
    Энгийн төрлийн хөрвүүлэлт: Илэрхийлэл
  • 17.
    • Java хэлэнд илэрхийллийн төрлийг өргөтгөхдөө илэрхийлэл дэх оператор нь унар оператор уу, бинар оператор уу гэдгээс хамаардаг.
    • Byte болон short операнд орсон илэрхийллийн үр дүнг автоматаар өргөтгөн int төрөлд хөрвүүлэхдээ дараах хэдэн зарчмыг баримтална. Үүнд:
      • Хэрэв 2 тын оператор бүхий илэрхийллийн аль нэг операнд нь double бол нөгөө операндыг нь double төрөл рүү өргөтгөнө.
      • Үгүй бол хэрэв 2 тын оператор бүхий илэрхийллийн аль нэг операнд нь float бол нөгөө операндыг нь float төрөл рүү өргөтгөнө.
      • Үгүй бол хэрэв 2 тын оператор бүхий илэрхийллийн аль нэг операнд нь long бол нөгөө операндыг нь long төрөл рүү өргөтгөнө.
      • Үгүй бол 2 операторыг хоёулангий нь int төрөл рүү өргөтгөнө.
    Энгийн төрлийн хөрвүүлэлт: Илэрхийлэл
  • 18. Энгийн төрлийн хөрвүүлэлт: Илэрхийлэл Програмын double result=((f*b)+(i/c)-(d*s)); гэсэн мөрөнд тайлбар хийе. ( f*b) илэрхийлэлд b операндын төрлийг float төрлөөр өргөтгөн үр дүн нь float төрөл гарна. ( i/c) илэрхийлэлд c операндын төрлийг int төрлөөр өргөтгөн үр дүн нь int төрөл гарна. ( d*s) илэрхийлэлд s операндын төрлийг double төрлөөр өргөтгөн үр дүн нь double төрөл гарна.
  • 19. Энгийн төрлийн хөрвүүлэлт: Илэрхийлэл Дээрх дэд илэрхийллийн үр дүн болох float, int болон double төрлийн операндууд дээр үйлдэл хийхдээ float, int опеарандуудын нийлбэрийн үр дүн float төрөл гарна. float, double опеарандуудын нийлбэрийн үр дүн double төрөл гарна. Ийнхүү result хувьсагч нь илэрхийллийн эцсийн үр дүн болох double төрөл хүртэл өргөтгөгдан гарч байна.
  • 20.
    • Заалт төрлийн дараах хэлбэрүүд байдаг. Үүнд:
      • Клас
      • Интерфейс
      • Массив
    • Утга олгох
      • Oldtype x= new Oldtype;
      • Newtype y=x; // Заалт төрлийн хувьсагчдын утга олголт
    • Oldtype нь Класс ,Интерфейс, Массив байх боломжтойгоос гадна Newtype нь мөн Класс ,Интерфейс, Массив байх боломжтой бөгөөд энд тэдгээрийн комбинаци болох 3*3 =9 тохиолдлыг авч үзэх шаардлагатай.
    Заалт төрлийн хөрвүүлэлт
  • 21. Заалт төрлийн хөрвүүлэлт Хуучин төрлийг шинэ төрөл рүү хөрвүүлэх нь Oldtype нь класс бол Oldtype нь интерфейс бол Oldtype нь массив бол Newtype нь класс бол Oldtype нь Newtype -ийнхаа хүү класс байна Newtype нь Object байх ёстой Newtype нь Object байх ёстой Newtype нь интерфейс бол Oldtype нь Newtype интерфейсийг хэрэгжүүлэгч байна Oldtype нь Newtype интерфейсийн дэд интерфейс байна Newtype нь Cloneable байх ёстой Newtype нь массив бол Компилятор алдаа заана Компилятор алдаа заана Newtype нь Oldtype - руугаа автоматаар хөрвүүлэгдэх боломжтой.
  • 22. Заалт төрлийн хөрвүүлэлт
    • Дээрх хүснэгтээс дараах дүгнэлтийг хийж болно.
      • Интерфейсийг
        • интерфейс рүү
        • Object класс руу хөрвүүлэх боломжтой
      • Классыг
        • Класс руу автоматаар хөрвүүлж болно. Гэхдээ хуучин төрөл нь шинэ төрлийнхээ хүү класс байна. Эндээс “Эх классын заалтаар хүү классын объектыг заалгаж болно. Харин эсрэгээр хүү классын заалтаар эх классын объектыг заалгавал компилятор алдаа заах бөгөөд энд төрөл хувиргалт (cast) -ыг хийх шаардлагатай ” гэсэн дүгнэлтийг хийж болно.
        • Интерфейс автоматаар рүү хөрвүүлж болно. Гэхдээ хуучин төрөл нь шинэ төрлийн интерфейсийг хэрэгжүүлэгч класс байна
      • Массивыг
        • Object класс руу хөрвүүлэх боломжтой
        • Cloneable эсвэл Serialazable интерфейс рүү хөрвүүлэх боломжтой
        • Массив руу хөрвүүлэх боломжтой. Гэхдээ хуучин төрөл нь шинэ төрөл рүүгээ автоматаар хөрвөгдөх үед л энэ нь боломжтой.
  • 23.
    • Жишээ болгож дараах иерархийг авч үзье.
    Заалт төрлийн хөрвүүлэлт Object Animal Bird Implements Flyable Tagtaa Boljmor Haraatsai Хуучин төрөл Tagtaa нь Bird гэсэн шинэ төрлийнхөө хүү класс нь тул хөрвүүлэлтийг автоматаар хийнэ
  • 24.
    • Жишээ болгож дараах иерархийг авч үзье.
    Заалт төрлийн хөрвүүлэлт Асуудлыг хэрхэн шийдэх вэ??? Object Animal Bird Implements Flyable Tagtaa Boljmor Haraatsai Хуучин төрөл Bird нь Tagtaa гэсэн шинэ төрлийнхөө хүү нь биш эх класс нь тул компилятор алдаа заана Мөрийг tagtaa = (Tagtaa)bird; мөрөөр солих. Ингэснээр compiletime алдаа заахгүй боловч runtime алдаа заана
  • 25.
    • Өмнөх хуудсанд дурдагдсан runtime error яагаад үүсч байна вэ? гэсэн асуулт тавигдана. Үүнийг тайлбарлахын тулд дараах жишээг авч үзье.
    ClassCastException No error in CompileTime RunTime Error