JavaJava · Chapterبەش 10 · Lectureوانە 10.3
Inheritance and Polymorphismبۆماوە و فرەشێوەیی
Build new classes from old ones. extends and the is-a test; what a subclass inherits and what private and protected mean for it; super(...) and the constructor chain; overriding with @Override and how it differs from overloading; polymorphism, where one Vehicle variable holds a car, a bus or a motorbike and the object's own method runs; casting and instanceof; Object as the root of every class, with toString and equals; final classes and methods. Pattern matching and sealed classes appear as extras.
دروستکردنی نوێ لە کۆنەوە. extends و تاقیکردنەوەی is-a؛ چی بە وەردەگرێت و private و protected چییان بۆ دەگەیەنن؛ super(...) و زنجیرەی ؛ بە @Override و جیاوازییەکەی لەگەڵ ؛ ، کە یەک Vehicle ئۆتۆمبێل، پاس یان ماتۆڕسکیل هەڵدەگرێت و خودی جێبەجێ دەبێت؛ و instanceof؛ Object وەک ڕەگی هەموو لەگەڵ toString و equals؛ و final. pattern matching و sealed وەک زیادە دێن.
What you will learnچی فێر دەبیت
- Write subclasses with extends, test the design with is-a, and explain what is and is not inherited.
- Call superclass constructors with super(...) and fix the javac errors about them.
- Override methods with @Override, use super.method(), and tell overriding from overloading.
- Use polymorphism with superclass variables and lists, and cast safely with instanceof.
- Override toString, equals and hashCode, and use final classes and methods.
- بە
extendsبنووسیت، دیزاینەکە بە is-a تاقی بکەیتەوە و ڕوون بکەیتەوە چی بە دەدرێت و چی نا. - بە
super(...)بانگی بکەیت و هەڵەکانی javac لەبارەیان چاک بکەیتەوە. - بە
@Overrideدووپاتە پێناسە بکەیتەوە،super.method()بەکار بهێنیت و لە جیا بکەیتەوە. - بە و بەکار بهێنیت و بە
instanceofبە سەلامەتی جۆر بگۆڕیت. toString،equalsوhashCodeدووپاتە پێناسە بکەیتەوە و وfinalبەکار بهێنیت.
Why inheritance?بۆچی بۆماوە؟
A bus company in Hawler keeps cars, buses and motorbikes. Every vehicle has a number plate and a number of seats, and every vehicle should be able to describe itself. Three separate classes, Car, Bus and Motorbike, would repeat the same fields and the same describe() method three times, and every fix would have to be made three times too.
کۆمپانیایەکی گواستنەوە لە هەولێر ئۆتۆمبێل، پاس و ماتۆڕسکیلی هەیە. هەموو ئامرازێکی گواستنەوە ژمارەیەک (plate) و چەند کورسییەکی هەیە و هەمووشیان دەبێت بتوانن خۆیان وەسف بکەن. سێ جیاواز، Car، Bus و Motorbike، هەمان و هەمان describe() سێ جار دووپاتە دەکەنەوە و هەر چاککردنێکیش دەبێت سێ جار بکرێت.
Inheritance solves this. You write the shared part once, in a class Vehicle, and the other classes extend it: class Car extends Vehicle. Vehicle is the superclass (also called the parent or base class); Car is a subclass (a child or derived class). The subclass receives the members of the superclass and adds only what is new. Java's own classes are built this way too: all exceptions form one family of classes (The exception family).
ئەم کێشەیە چارەسەر دەکات. بەشە هاوبەشەکە یەک جار لە بە ناوی Vehicle دەنووسیت و تر لێی extends دەکەن: class Car extends Vehicle. Vehicle و Car . ئەندامەکانی وەردەگرێت و تەنیا ئەوەی نوێیە زیاد دەکات. خودی Javaـش بەم شێوەیە دروست کراون: هەموو یەک خێزانی پێک دەهێنن (خێزانی هەڵاوێردەکان).
Making a new from an existing one: the new class (subclass) gets the fields and methods of the old one (superclass) and can add or change some. Dart allows single inheritance: a class extends only one class.
دروستکردنی نوێیە لە کلاسێکی هەبووەوە: کلاسە نوێیەکە (subclass) ستوون و میتۆدەکانی کلاسە کۆنەکە (superclass) وەردەگرێت و دەتوانێت هەندێکیان زیاد بکات یان بگۆڕێت. Dart تەنیا یەک بۆماوە ڕێگە دەدات: هەر کلاسێک تەنیا یەک کلاس extends دەکات.
extends: a subclass receives the superclass's membersextends: کلاسی منداڵ ئەندامەکانی کلاسی باوک وەردەگرێت
Here is the vehicle example in Java. Vehicle has two fields and a method. Car and Bus each add one field and write nothing else, yet a Car object has plate, seats and describe() as well:
ئەمە نموونەی ئامرازەکانی گواستنەوەیە بە Java. Vehicle دوو و هەیە. Car و Bus هەر یەکەیان تەنیا زیاد دەکەن و هیچی تر نانووسن، کەچی Car ئەمانەشی هەیە: plate، seats و describe():
class Vehicle {
String plate;
int seats;
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Car extends Vehicle {
int doors;
}
class Bus extends Vehicle {
String route;
}
public class Garage {
public static void main(String[] args) {
Car car = new Car();
car.plate = "HW-1234";
car.seats = 5;
car.doors = 4;
car.describe();
System.out.println("Doors: " + car.doors);
Bus bus = new Bus();
bus.plate = "DH-5678";
bus.seats = 45;
bus.route = "Hawler - Duhok";
bus.describe();
System.out.println("Route: " + bus.route);
}
}$ java Garage HW-1234: 5 seats Doors: 4 DH-5678: 45 seats Route: Hawler - Duhok
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1-8
The superclass: the shared part, written once.
: بەشە هاوبەشەکە، یەک جار نووسراوە.
- Lineدێڕی 10-11
extends Vehicle: Car receives plate, seats and describe(), and adds doors.extends Vehicle:Carئەمانە وەردەگرێت:plate،seatsوdescribe()؛doorsـیش زیاد دەکات.- Lineدێڕی 21
An inherited field, used like an own field.
بۆماوەگیراو، وەک خۆی بەکار دێت.
- Lineدێڕی 24
The method was written only in Vehicle, but it works on a Car.
تەنیا لە
Vehicleـدا نووسراوە، بەڵام لەسەرCarـیش کار دەکات.
extends: a subclass receives the superclass's membersextends: کلاسی منداڵ ئەندامەکانی کلاسی باوک وەردەگرێت
The is-a testتاقیکردنەوەی is-a
Use extends only when the sentence A ___ is a ___ is true. A car is a vehicle, so Car extends Vehicle fits. A bus is not a car, so Bus must not extend Car. When the true sentence is has a, use a field instead: a bus has a driver, so Bus gets a field Driver driver;, and it does not extend Driver.
extends تەنیا کاتێک بەکار بهێنە کە ڕستەی «___ جۆرێکە لە ___» ڕاست بێت. ئۆتۆمبێل جۆرێکە لە ئامرازی گواستنەوە، بۆیە Car extends Vehicle دەگونجێت. پاس جۆرێک نییە لە ئۆتۆمبێلی سواری، بۆیە نابێت Bus لە Car extends بکات. کاتێک ڕستە ڕاستەکە «...ی هەیە» بێت، لە جیاتی ئەوە بەکار بهێنە: پاس شۆفێرێکی هەیە، بۆیە Bus Driver driver; وەردەگرێت و لە Driver extends ناکات.
Database designers ask the same question when they specialise an entity (Inheritance in E-R models), and Dart classes inherit in the same way (Inheritance in Dart).
دیزاینەرانی کاتێک تایبەت دەکەن هەمان پرسیار دەکەن (بۆماوە لە مۆدێلی E-R) و Dart بە هەمان شێوە وەردەگرن (بۆماوە لە Dart).
extends: a subclass receives the superclass's membersextends: کلاسی منداڵ ئەندامەکانی کلاسی باوک وەردەگرێت
One superclass, many levelsیەک کلاسی باوک، چەندین ئاست
A subclass can itself be extended. SchoolBus extends Bus, and Bus extends Vehicle, so a school bus has the members of both:
خۆیشی دەتوانێت extends بکرێت. SchoolBus extends Bus و Bus extends Vehicle، بۆیە پاسی قوتابخانە ئەندامەکانی هەردووکیانی هەیە:
class Vehicle {
String plate;
int seats;
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Bus extends Vehicle {
String route;
}
class SchoolBus extends Bus {
String school;
}
public class Levels {
public static void main(String[] args) {
SchoolBus sb = new SchoolBus();
sb.plate = "DH-3307";
sb.seats = 30;
sb.route = "Old town - school";
sb.school = "School No. 5";
sb.describe();
System.out.println(sb.route + " (" + sb.school + ")");
}
}$ java Levels DH-3307: 30 seats Old town - school (School No. 5)
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 14-15
Two levels: SchoolBus gets route from Bus and plate, seats and describe() from Vehicle.
دوو ئاست:
SchoolBusrouteلەBusـەوە وplate،seatsوdescribe()لەVehicleـەوە وەردەگرێت.
But every Java class has exactly one direct superclass. class TaxiBus extends Car, Bus is not Java: javac stops with the short message '{' expected. A class combines abilities from several places with interfaces instead (Several interfaces).
بەڵام هەموو Java ڕێک یەک ڕاستەوخۆی هەیە. class TaxiBus extends Car, Bus Java نییە: javac بە پەیامی کورتی '{' expected دەوەستێت. بە توانا لە چەند شوێنێکەوە کۆ دەکاتەوە (چەند نێوبەستەیەک).
What a subclass inherits, and what notکلاسی منداڵ چی بە بۆماوە وەردەگرێت و چی نا
A subclass inherits the public and protected members of its superclass, and the members with no modifier when both classes are in the same package. Two things are not inherited: private members and constructors. A private field still exists inside every object; only the superclass's own code may name it. Here km is private, yet the inherited methods drive() and getKm() work with it for Car:
ئەندامە public و protectedـەکانی بە وەردەگرێت، هەروەها ئەندامە بێ دیاریکەرەکان کاتێک هەردوو لە هەمان بن. دوو شت بە نادرێن: ئەندامە privateـەکان و . private هێشتا لە ناو هەموو هەیە؛ تەنیا کۆدی خودی دەتوانێت ناوی بهێنێت. لێرەدا km privateـە، کەچی بۆماوەگیراوەکان، drive() و getKm()، بۆ Car لەگەڵیدا کار دەکەن:
class Vehicle {
String plate;
private int km; // only Vehicle's own code may use it
void drive(int distance) {
km = km + distance;
}
int getKm() {
return km;
}
}
class Car extends Vehicle {
void trip() {
drive(120);
System.out.println(plate + " has driven " + getKm() + " km");
}
}
public class Odometer {
public static void main(String[] args) {
Car car = new Car();
car.plate = "HW-1234";
car.trip();
car.trip();
}
}$ java Odometer HW-1234 has driven 120 km HW-1234 has driven 240 km
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3
Private: only code inside Vehicle may use km.
private: تەنیا کۆدی ناو
Vehicleدەتوانێتkmبەکار بهێنێت.- Lineدێڕی 15-17
Car calls the inherited public methods; they change km for it.
Carبانگی بۆماوەگیراوەکان دەکات؛ ئەوانkmبۆ ئەو دەگۆڕن.
A method in Car that writes km = 0; does not compile: km has private access in Vehicle. That is encapsulation at work (Encapsulation): even a subclass goes through the superclass's methods.
لە Carـدا کە km = 0; بنووسێت کۆمپایل نابێت: km has private access in Vehicle. ئەمە لە کاردا (کەپسوولکردن): تەنانەت بە تێدەپەڕێت.
What a subclass inherits, and what notکلاسی منداڵ چی بە بۆماوە وەردەگرێت و چی نا
protected: open to subclassesprotected: کراوەیە بۆ کلاسەکانی منداڵ
protected lies between package access and public (Access modifiers): classes of the same package may use the member, and so may a subclass in any package. Here Vehicle is in the package vehicles (Your own package), and Taxi in the package app extends it:
protected لە نێوان دەستڕاگەیشتنی و publicـدایە (دیاریکەرەکانی دەستڕاگەیشتن): هەمان دەتوانن ئەندامەکە بەکار بهێنن، هەروەها لە هەر بێت. لێرەدا Vehicle لە vehiclesـدایە (پاکێجەکەی خۆت) و Taxi لە app لێی extends دەکات:
package vehicles;
public class Vehicle {
protected String plate;
public void describe() {
System.out.println("Vehicle " + plate);
}
}package app;
import vehicles.Vehicle;
public class Taxi extends Vehicle {
public Taxi(String plate) {
this.plate = plate; // a subclass: allowed
}
public void sign() {
System.out.println("TAXI " + plate);
}
}Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 7
Taxi is a subclass, so it may use the protected field, although it is in another package.
Taxi، بۆیە دەتوانێت protectedـەکە بەکار بهێنێت، هەرچەندە لە ترە.
package app;
import vehicles.Garage;
public class Main {
public static void main(String[] args) {
Taxi t = new Taxi("SL-9012");
t.sign();
Garage.check(t);
System.out.println(t.plate);
}
}$ javac vehicles/*.java app/*.java
app/Main.java:10: error: plate has protected access in Vehicle
System.out.println(t.plate);
^
1 errorMain is in another package and is not a subclass, so t.plate is refused. A good habit: keep fields private and make protected only what subclasses really need, often a method rather than a field.
Main لە ترە و نییە، بۆیە t.plate ڕەت دەکرێتەوە. خووی باش: private بهێڵەوە و تەنیا ئەوە بکە بە protected کە بە ڕاستی پێویستیانە، زۆرجار نەک .
super(...): the superclass part is built firstsuper(...): سەرەتا بەشی کلاسی باوک دروست دەکرێت
Constructors are not inherited, so Car must write its own. When Vehicle has a constructor Vehicle(String plate, int seats), the first statement of the Car constructor is super(plate, 5);: it runs the superclass constructor, which fills the Vehicle part of the new object. Then Car fills its own part:
بە نادرێن، بۆیە Car دەبێت هی خۆی بنووسێت. کاتێک Vehicle Vehicle(String plate, int seats)ـی هەیە، یەکەم Car بریتییە لە super(plate, 5);: جێبەجێ دەکات کە بەشی Vehicleـی نوێیەکە پڕ دەکاتەوە. پاشان Car بەشەکەی خۆی پڕ دەکاتەوە:
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
System.out.println("Vehicle part ready: " + plate);
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
super(plate, 5);
this.doors = doors;
System.out.println("Car part ready: " + doors + " doors");
}
}
public class Build {
public static void main(String[] args) {
Car car = new Car("HW-1234", 4);
System.out.println(car.plate + ", " + car.seats + " seats, " + car.doors + " doors");
}
}$ java Build Vehicle part ready: HW-1234 Car part ready: 4 doors HW-1234, 5 seats, 4 doors
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 16
The plate and 5 seats go up to the Vehicle constructor.
ژمارەکە و 5 کورسی دەچن بۆ
Vehicle.- Lineدێڕی 17
Only then does Car set its own field.
تەنیا ئەوکات
Carخۆی دادەنێت.
super(...): the superclass part is built firstsuper(...): سەرەتا بەشی کلاسی باوک دروست دەکرێت
No super(...)? javac adds super()super(...) نییە؟ javac خۆی super() زیاد دەکات
Every constructor begins by building the superclass part. If you write no super(...) (and no this(...)), javac puts a hidden super(); in, a call with no arguments. That is why the classes of the last lessons worked: their superclass is Object, which has a no-argument constructor (The default constructor). But this Vehicle has only Vehicle(String, int):
هەموو بە دروستکردنی بەشی دەست پێ دەکات. ئەگەر هیچ super(...) (یان this(...)) نەنووسیت، javac super();ـێکی شاراوە دادەنێت، بانگکردنێک بێ . هەر بۆیە وانەکانی پێشوو کاریان کرد: Objectـە کە بێ هەیە (دروستکەری بنەڕەتی). بەڵام ئەم Vehicleـە تەنیا Vehicle(String, int)ـی هەیە:
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
this.plate = plate;
this.doors = doors;
}
}
public class Build {
public static void main(String[] args) {
Car car = new Car("HW-1234", 4);
}
}$ javac Build.java
Build.java:14: error: constructor Vehicle in class Vehicle cannot be applied to given types;
Car(String plate, int doors) {
^
required: String,int
found: no arguments
reason: actual and formal argument lists differ in length
1 errorThe message points at the Car constructor itself: the hidden super() finds no matching constructor. Fix it by writing super(plate, 5); as the first line, or by giving Vehicle a no-argument constructor too.
پەیامەکە ئاماژە بۆ خودی Car دەکات: super()ـە شاراوەکە هیچ گونجاو نادۆزێتەوە. بە نووسینی super(plate, 5); وەک یەکەم دێڕ چاکی بکەرەوە، یان بێ بدە بە Vehicle.
super(...): the superclass part is built firstsuper(...): سەرەتا بەشی کلاسی باوک دروست دەکرێت
super(...) must be the first statementsuper(...) دەبێت یەکەم ڕستە بێت
Like this(...) (this(...)), super(...) must be the first statement of a constructor, so the superclass part is ready before the subclass uses it:
وەک this(...) (this(...))، super(...) دەبێت یەکەم بێت، بۆ ئەوەی بەشی پێش ئەوەی بەکاری بهێنێت ئامادە بێت:
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
this.doors = doors;
super(plate, 5);
}
}
public class Build {
public static void main(String[] args) {
Car car = new Car("HW-1234", 4);
}
}$ javac Build.java
Build.java:16: error: call to super must be first statement in constructor
super(plate, 5);
^
1 errorsuper(...): the superclass part is built firstsuper(...): سەرەتا بەشی کلاسی باوک دروست دەکرێت
The constructor chainزنجیرەی دروستکەرەکان
With more levels, every constructor first calls the one above it, all the way up to Object. The calls climb up; then the constructor bodies run from the top down. So the Vehicle part is ready first, then the Bus part, and the SchoolBus part last:
بە ئاستی زیاتر، هەر سەرەتا بانگی ئەوەی سەرووی خۆی دەکات، تا دەگاتە Object. بانگکردنەکان بۆ سەرەوە دەچن؛ پاشان جەستەی لە سەرەوە بۆ خوارەوە جێبەجێ دەبن. بۆیە سەرەتا بەشی Vehicle ئامادە دەبێت، پاشان بەشی Bus و لە کۆتاییدا بەشی SchoolBus:
class Vehicle {
Vehicle(String plate) {
System.out.println("1. Vehicle: plate " + plate);
}
}
class Bus extends Vehicle {
Bus(String plate, String route) {
super(plate);
System.out.println("2. Bus: route " + route);
}
}
class SchoolBus extends Bus {
SchoolBus(String plate) {
super(plate, "Old town - school");
System.out.println("3. SchoolBus: ready");
}
}
public class Chain {
public static void main(String[] args) {
new SchoolBus("DH-3307");
}
}$ java Chain 1. Vehicle: plate DH-3307 2. Bus: route Old town - school 3. SchoolBus: ready


Overriding: a new version of an inherited methodپێناسەکردنەوەی میتۆد: وەشانێکی نوێی میتۆدێکی بۆماوەگیراو
An inherited method does not always fit. Vehicle's describe() prints the seats, but a car should mention its doors and a bus its route. A subclass overrides a method by writing a method with the same name and the same parameters; for its objects the new version replaces the inherited one. Mark it with @Override:
بۆماوەگیراو هەمیشە گونجاو نییە. describe()ـی Vehicle کورسییەکان چاپ دەکات، بەڵام ئۆتۆمبێل دەبێت دەرگاکانی باس بکات و پاس ڕێگاکەی. بە نووسینی بە هەمان ناو و هەمان ئەو دووپاتە پێناسە دەکاتەوە؛ بۆ ئەو، وەشانە نوێیەکە جێگەی وەشانە بۆماوەگیراوەکە دەگرێتەوە. بە @Override نیشانەی بکە:
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
super(plate, 5);
this.doors = doors;
}
@Override
void describe() {
System.out.println(plate + ": a car with " + doors + " doors");
}
}
class Bus extends Vehicle {
String route;
Bus(String plate, int seats, String route) {
super(plate, seats);
this.route = route;
}
@Override
void describe() {
System.out.println(plate + ": a bus on " + route);
}
}
class Motorbike extends Vehicle {
Motorbike(String plate) {
super(plate, 2);
}
}
public class Overriding {
public static void main(String[] args) {
Car car = new Car("HW-1234", 4);
Bus bus = new Bus("DH-5678", 45, "Hawler - Duhok");
Motorbike bike = new Motorbike("SL-9012");
car.describe();
bus.describe();
bike.describe();
}
}$ java Overriding HW-1234: a car with 4 doors DH-5678: a bus on Hawler - Duhok SL-9012: 2 seats
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 23-25
Car's own describe(): same name, same (empty) parameter list.
describe()ـی خودیCar: هەمان ناو و هەمان لیستی (بەتاڵ).- Lineدێڕی 43-45
Motorbike overrides nothing: it keeps Vehicle's describe().
Motorbikeهیچ دووپاتە پێناسە ناکاتەوە:describe()ـیVehicleدەهێڵێتەوە.
Car describe() دووپاتە پێناسە دەکاتەوە؛ Motorbike هی Vehicle دەهێڵێتەوەCêITWriting a new version of an inherited in a , with the same name. In Dart the line above it is marked @override; the new version can still call the old one with super.
نووسینی وەشانێکی نوێی بۆماوەگیراو لە ، بە هەمان ناو. لە دێڕی سەرەوەی بە @override نیشانە دەکرێت؛ وەشانە نوێیەکە هێشتا دەتوانێت بە super بانگی وەشانە کۆنەکە بکات.
Overriding: a new version of an inherited methodپێناسەکردنەوەی میتۆد: وەشانێکی نوێی میتۆدێکی بۆماوەگیراو
super.method(): reuse the old versionsuper.method(): وەشانە کۆنەکە بەکار بهێنەوە
An override does not have to start from nothing. Inside it, super.describe() runs the superclass's version, and the override adds its own lines after it:
پێویست ناکات لە سفرەوە دەست پێ بکات. لە ناویدا، super.describe() وەشانەکەی جێبەجێ دەکات و وەشانە نوێیەکە دێڕەکانی خۆی لە دوایەوە زیاد دەکات:
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
super(plate, 5);
this.doors = doors;
}
@Override
void describe() {
super.describe(); // Vehicle's version first
System.out.println(" and " + doors + " doors"); // then the car's extra line
}
}
public class SuperCall {
public static void main(String[] args) {
Car car = new Car("HW-1234", 4);
car.describe();
}
}$ java SuperCall HW-1234: 5 seats and 4 doors
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 25
Runs Vehicle's describe() for this object.
describe()ـیVehicleبۆ ئەم جێبەجێ دەکات.
Overriding: a new version of an inherited methodپێناسەکردنەوەی میتۆد: وەشانێکی نوێی میتۆدێکی بۆماوەگیراو
@Override: let javac check you@Override: با javac بتپشکنێت
@Override is an annotation, a note for javac: it asks javac to make sure that the method really overrides an inherited one. A typo in the name then stops the compile at once:
@Override تێبینییەکە بۆ javac (annotation): داوا لە javac دەکات دڵنیا ببێتەوە کە ئەو بە ڕاستی بۆماوەگیراو دووپاتە پێناسە دەکاتەوە. ئەوکات هەڵەیەکی نووسین لە ناوەکەدا دەستبەجێ کۆمپایلکردن دەوەستێنێت:
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
super(plate, 5);
this.doors = doors;
}
@Override
void descibe() {
System.out.println(plate + ": a car with " + doors + " doors");
}
}
public class Typo {
public static void main(String[] args) {
Car car = new Car("HW-1234", 4);
car.describe();
}
}$ javac Typo.java
Typo.java:23: error: method does not override or implement a method from a supertype
@Override
^
1 errorWithout @Override the same typo compiles without a warning: descibe() becomes a new, separate method, and car.describe() still runs Vehicle's old version:
بەبێ @Override هەمان هەڵەی نووسین بەبێ ئاگادارکردنەوە کۆمپایل دەبێت: descibe() دەبێتە نوێی جیاواز و car.describe() هێشتا وەشانە کۆنەکەی Vehicle جێبەجێ دەکات:
$ java Typo HW-1234: 5 seats
So write @Override on every override. The same check caught a tostring() typo in Printing an object.
بۆیە لە سەرووی هەموو @Override بنووسە. هەمان پشکنین هەڵەی نووسینی tostring()ـی لە چاپکردنی ئۆبجێکتێک گرت.
Overriding: a new version of an inherited methodپێناسەکردنەوەی میتۆد: وەشانێکی نوێی میتۆدێکی بۆماوەگیراو
The rules for overridingیاساکانی پێناسەکردنەوەی میتۆد
javac checks every override against these rules; each broken rule has its own message:
javac هەموو بەپێی ئەم یاسایانە دەپشکنێت؛ هەر یاسایەکی شکاو پەیامی خۆی هەیە:
| Ruleیاسا | If you break itئەگەر بیشکێنیت |
|---|---|
| The same name and the same parameter typesهەمان ناو و هەمان جۆری | It is a new method (an overload), not an override نوێیە ()، نەک |
| The same return type (or a subclass of it)هەمان (یان ئەو) | return type String is not compatible with void |
The same access or wider: public stays publicهەمان دەستڕاگەیشتن یان فراوانتر: public هەر public دەمێنێتەوە | attempting to assign weaker access privileges; was public |
The inherited method is not final بۆماوەگیراوەکە final نییە | overridden method is final |
| Only instance methods are overriddenتەنیا دووپاتە پێناسە دەکرێنەوە | private methods are not inherited; a static method with the same signature only hides the other one privateـەکان بە نادرێن؛ static بە هەمان تەنیا ئەوی تر دەشارێتەوە |
class Vehicle {
String plate;
public void describe() {
System.out.println("Vehicle " + plate);
}
}
class Car extends Vehicle {
void describe() {
System.out.println("Car " + plate);
}
}
public class Weaker {
public static void main(String[] args) {
new Car().describe();
}
}$ javac Weaker.java
Weaker.java:10: error: describe() in Car cannot override describe() in Vehicle
void describe() {
^
attempting to assign weaker access privileges; was public
1 errorOverriding or overloading?پێناسەکردنەوەی میتۆد یان فرەپێناسەکردنی میتۆد؟
The two words sound alike but mean different things. Overloading (One name, several methods) gives one class several methods with the same name and different parameters; javac picks one from the arguments. Overriding gives a subclass a method with the same name and parameters as an inherited one; the object picks it while the program runs. One class can do both:
ئەم دوو وشەیە لە یەک دەچن، بەڵام واتای جیاوازیان هەیە. (یەک ناو، چەند میتۆدێک) چەند بە هەمان ناو و جیاواز دەدات بە یەک ؛ javac بەپێی یەکێکیان هەڵدەبژێرێت. بە هەمان ناو و هەمان بۆماوەگیراو دەدات بە ؛ لە کاتی کارکردنی هەڵیدەبژێرێت. یەک دەتوانێت هەردووکیان بکات:
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Bus extends Vehicle {
String route;
Bus(String plate, int seats, String route) {
super(plate, seats);
this.route = route;
}
@Override
void describe() { // overriding: same signature
System.out.println(plate + ": a bus on " + route);
}
void describe(int passengers) { // overloading: another parameter list
System.out.println(plate + ": " + (seats - passengers) + " seats free");
}
}
public class Both {
public static void main(String[] args) {
Bus bus = new Bus("DH-5678", 45, "Hawler - Duhok");
bus.describe();
bus.describe(38);
}
}$ java Both DH-5678: a bus on Hawler - Duhok DH-5678: 7 seats free
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 10
Overriding: the same signature as in Vehicle.
: هەمان وەک لە
Vehicleـدا.- Lineدێڕی 28
Overloading: the same name with another parameter list.
: هەمان ناو بە لیستێکی تری .
| Compareبەراورد | Overloading | Overriding |
|---|---|---|
| Whereلە کوێ | The same class (or an inherited name)هەمان (یان ناوێکی بۆماوەگیراو) | A subclass |
| Parameters | Differentجیاواز | The sameهەمان |
| Who choosesکێ هەڵدەبژێرێت | javac, from the argumentsjavac، بەپێی | The object, while the program runs، لە کاتی کارکردنی |
@Override@Override | Noنەخێر | Yesبەڵێ |
Polymorphism: one call, many formsفرەشێوەیی: یەک بانگکردن، چەندین شێوە
A variable of a superclass type may refer to an object of any subclass, because a car is a vehicle: Vehicle v = new Car(...). When you call v.describe(), Java runs the version of the object that v refers to at that moment, not the version of the variable's type. This is polymorphism ('many forms'); the choice made while the program runs is called dynamic dispatch:
بە جۆری دەتوانێت ئاماژە بۆ هەر بکات، چونکە ئۆتۆمبێل جۆرێکە لە ئامرازی گواستنەوە: Vehicle v = new Car(...). کاتێک v.describe() بانگ دەکەیت، Java وەشانەکەی ئەو جێبەجێ دەکات کە v لەو ساتەدا ئاماژەی بۆ دەکات، نەک وەشانەکەی جۆری . ئەمە ـە («چەندین شێوە»)؛ ئەو هەڵبژاردنەی لە کاتی کارکردنی دەکرێت پێی دەوترێت dynamic dispatch:
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
super(plate, 5);
this.doors = doors;
}
@Override
void describe() {
System.out.println(plate + ": a car with " + doors + " doors");
}
}
class Bus extends Vehicle {
String route;
Bus(String plate, int seats, String route) {
super(plate, seats);
this.route = route;
}
@Override
void describe() {
System.out.println(plate + ": a bus on " + route);
}
}
class Motorbike extends Vehicle {
Motorbike(String plate) {
super(plate, 2);
}
}
public class Dispatch {
public static void main(String[] args) {
Vehicle v = new Car("HW-1234", 4);
v.describe();
v = new Bus("DH-5678", 45, "Hawler - Duhok");
v.describe();
v = new Motorbike("SL-9012");
v.describe();
}
}$ java Dispatch HW-1234: a car with 4 doors DH-5678: a bus on Hawler - Duhok SL-9012: 2 seats
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 51
A Vehicle variable, a Car object.
Vehicle،Car.- Lineدێڕی 54
The same variable now refers to a Bus.
هەمان ئێستا ئاماژە بۆ
Busـێک دەکات.


One call that behaves differently for different kinds of . A variable of a type can hold an object of any ; when you call a method that the subclass overrides, Java runs the real object's version, so shape.area() works for a circle and for a square.
یەک بانگکردن کە بۆ جیاواز بە شێوەی جیاواز کار دەکات. بە جۆری دەتوانێت ئۆبجێکتی هەر هەڵبگرێت؛ کاتێک بانگ دەکەیت کە لە دووپاتە پێناسە کراوە، Java وەشانەکەی ئۆبجێکتە ڕاستەقینەکە جێبەجێ دەکات، بۆیە shape.area() بۆ بازنە و بۆ چوارگۆشە کار دەکات.
Polymorphism: one call, many formsفرەشێوەیی: یەک بانگکردن، چەندین شێوە
What may I call? Which version runs?چی دەتوانم بانگ بکەم؟ کام وەشان جێبەجێ دەبێت؟
Two separate checks happen. javac looks only at the variable's type: a Vehicle has no route, so v.route does not compile, even though v holds a Bus. When the program runs, the JVM looks at the object and runs its version of the method:
دوو پشکنینی جیاواز ڕوو دەدەن. javac تەنیا سەیری جۆری دەکات: Vehicle هیچ routeـێکی نییە، بۆیە v.route کۆمپایل نابێت، هەرچەندە v Bus هەڵدەگرێت. کاتێک کار دەکات، سەیری دەکات و وەشانەکەی ئەو لە جێبەجێ دەکات:
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
super(plate, 5);
this.doors = doors;
}
@Override
void describe() {
System.out.println(plate + ": a car with " + doors + " doors");
}
}
class Bus extends Vehicle {
String route;
Bus(String plate, int seats, String route) {
super(plate, seats);
this.route = route;
}
@Override
void describe() {
System.out.println(plate + ": a bus on " + route);
}
}
class Motorbike extends Vehicle {
Motorbike(String plate) {
super(plate, 2);
}
}
public class NoRoute {
public static void main(String[] args) {
Vehicle v = new Bus("DH-5678", 45, "Hawler - Duhok");
v.describe();
System.out.println(v.route);
}
}$ javac NoRoute.java
NoRoute.java:53: error: cannot find symbol
System.out.println(v.route);
^
symbol: variable route
location: variable v of type Vehicle
1 errorPolymorphism: one call, many formsفرەشێوەیی: یەک بانگکردن، چەندین شێوە
A list of vehiclesلیستێک لە Vehicle
Polymorphism pays off with lists. An ArrayList<Vehicle> (Creating an ArrayList) holds cars, buses and motorbikes together, one for-each loop calls describe() on each, and every object answers in its own way. A method with a Vehicle parameter accepts every kind of vehicle as well:
لەگەڵ سوودی خۆی پیشان دەدات. ArrayList<Vehicle> (دروستکردنی ArrayList) ئۆتۆمبێل، پاس و ماتۆڕسکیل پێکەوە هەڵدەگرێت، یەک بانگی describe() لەسەر هەر یەکێکیان دەکات و هەموو بە شێوەی خۆی وەڵام دەداتەوە. بە Vehicleـیش هەموو جۆرە ئامرازێکی گواستنەوە وەردەگرێت:
import java.util.ArrayList;
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
super(plate, 5);
this.doors = doors;
}
@Override
void describe() {
System.out.println(plate + ": a car with " + doors + " doors");
}
}
class Bus extends Vehicle {
String route;
Bus(String plate, int seats, String route) {
super(plate, seats);
this.route = route;
}
@Override
void describe() {
System.out.println(plate + ": a bus on " + route);
}
}
class Motorbike extends Vehicle {
Motorbike(String plate) {
super(plate, 2);
}
}
public class Fleet {
static void inspect(Vehicle v) {
System.out.print("Inspecting ");
v.describe();
}
public static void main(String[] args) {
ArrayList<Vehicle> fleet = new ArrayList<>();
fleet.add(new Car("HW-1234", 4));
fleet.add(new Bus("DH-5678", 45, "Hawler - Duhok"));
fleet.add(new Motorbike("SL-9012"));
int seats = 0;
for (Vehicle v : fleet) {
v.describe();
seats = seats + v.seats;
}
System.out.println(fleet.size() + " vehicles, " + seats + " seats");
inspect(fleet.get(1));
}
}$ java Fleet HW-1234: a car with 4 doors DH-5678: a bus on Hawler - Duhok SL-9012: 2 seats 3 vehicles, 52 seats Inspecting DH-5678: a bus on Hawler - Duhok
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 64-66
One loop for every kind of vehicle; seats is inherited, so every element has it.
یەک بۆ هەموو جۆرە ئامرازێک؛
seatsبۆماوەگیراوە، بۆیە هەموو توخمێک هەیەتی.
Casting between superclass and subclassگۆڕینی جۆر لە نێوان کلاسی باوک و کلاسی منداڵ
Going up is automatic: every Car is a Vehicle, so Vehicle v = car; needs nothing (an upcast). Going down needs a cast in brackets, as with numbers (Narrowing): Car c = (Car) v; (a downcast). Without the cast javac stops with incompatible types: Vehicle cannot be converted to Car. With a cast, javac trusts you, and the JVM checks the real object while the program runs:
گۆڕین بۆ سەرەوە خۆکارە: هەموو Carـێک Vehicleـە، بۆیە Vehicle v = car; پێویستی بە هیچ نییە (upcast). گۆڕین بۆ خوارەوە پێویستی بە نووسینی جۆرەکە لە ناو کەوانەدایە، وەک ژمارەکان (تەسککردنەوەی جۆر): Car c = (Car) v; (downcast). بەبێ ئەم گۆڕینە javac بە incompatible types: Vehicle cannot be converted to Car دەوەستێت. بە گۆڕینەکە، javac بڕوات پێ دەکات و لە کاتی کارکردنی ڕاستەقینەکە دەپشکنێت:
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
super(plate, 5);
this.doors = doors;
}
@Override
void describe() {
System.out.println(plate + ": a car with " + doors + " doors");
}
}
class Bus extends Vehicle {
String route;
Bus(String plate, int seats, String route) {
super(plate, seats);
this.route = route;
}
@Override
void describe() {
System.out.println(plate + ": a bus on " + route);
}
}
class Motorbike extends Vehicle {
Motorbike(String plate) {
super(plate, 2);
}
}
public class Cast {
public static void main(String[] args) {
Vehicle v = new Car("HW-1234", 4); // upcast: automatic
Car c = (Car) v; // downcast: you write (Car)
System.out.println("Doors: " + c.doors);
Bus b = (Bus) v; // compiles, but v is a Car
System.out.println(b.route);
}
}$ java Cast Doors: 4 Exception in thread "main" java.lang.ClassCastException: class Car cannot be cast to class Bus (Car and Bus are in unnamed module of loader 'app') at Cast.main(Cast.java:55)
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 52
Correct: v really holds a Car.
دروستە:
vبە ڕاستیCarـێک هەڵدەگرێت.- Lineدێڕی 55
Compiles, but the object is a Car, not a Bus.
کۆمپایل دەبێت، بەڵام
Carـە، نەکBus.
Casting between superclass and subclassگۆڕینی جۆر لە نێوان کلاسی باوک و کلاسی منداڵ
instanceof: check before you castinstanceof: پێش گۆڕینی جۆر بیپشکنە
v instanceof Bus is true when the object in v is a Bus (or a subclass of Bus), and false otherwise, also when v is null. Test first, then cast, and a ClassCastException cannot happen:
v instanceof Bus کاتێک trueـە کە ناو v Bus بێت (یان Bus)، ئەگینا falseـە، تەنانەت کاتێک v null بێت. سەرەتا تاقی بکەرەوە، پاشان جۆرەکە بگۆڕە، ئیتر ClassCastException ڕوو نادات:
import java.util.ArrayList;
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
super(plate, 5);
this.doors = doors;
}
@Override
void describe() {
System.out.println(plate + ": a car with " + doors + " doors");
}
}
class Bus extends Vehicle {
String route;
Bus(String plate, int seats, String route) {
super(plate, seats);
this.route = route;
}
@Override
void describe() {
System.out.println(plate + ": a bus on " + route);
}
}
class Motorbike extends Vehicle {
Motorbike(String plate) {
super(plate, 2);
}
}
public class Check {
public static void main(String[] args) {
ArrayList<Vehicle> fleet = new ArrayList<>();
fleet.add(new Car("HW-1234", 4));
fleet.add(new Bus("DH-5678", 45, "Hawler - Duhok"));
fleet.add(new Motorbike("SL-9012"));
for (Vehicle v : fleet) {
if (v instanceof Bus) {
Bus b = (Bus) v;
System.out.println(b.plate + " runs on " + b.route);
} else {
System.out.println(v.plate + " is not a bus");
}
}
Vehicle none = null;
System.out.println(none instanceof Vehicle);
}
}$ java Check HW-1234 is not a bus DH-5678 runs on Hawler - Duhok SL-9012 is not a bus false
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 59-60
The cast runs only when the test said yes.
تەنیا کاتێک جێبەجێ دەبێت کە تاقیکردنەوەکە وتی بەڵێ.
- Lineدێڕی 68
null is never an instance of anything.
nullهەرگیز نموونەی هیچ نییە.
Object: the root of every classObject: ڕەگی هەموو کلاسێک
A class without extends still has a superclass: java.lang.Object. class Vehicle { } means class Vehicle extends Object { }. So every chain of superclasses ends at Object, and every object has Object's methods, such as toString(), equals(), hashCode() and getClass(). getClass() can even show the chain:
کە extendsـی نەبێت هێشتا هەیە: java.lang.Object. class Vehicle { } واتە class Vehicle extends Object { }. بۆیە هەموو زنجیرەیەکی بە Object کۆتایی دێت و هەموو Objectـی هەیە، وەک toString()، equals()، hashCode() و getClass(). getClass() تەنانەت دەتوانێت زنجیرەکە پیشان بدات:
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
super(plate, 5);
this.doors = doors;
}
@Override
void describe() {
System.out.println(plate + ": a car with " + doors + " doors");
}
}
class Bus extends Vehicle {
String route;
Bus(String plate, int seats, String route) {
super(plate, seats);
this.route = route;
}
@Override
void describe() {
System.out.println(plate + ": a bus on " + route);
}
}
class Motorbike extends Vehicle {
Motorbike(String plate) {
super(plate, 2);
}
}
public class Root {
public static void main(String[] args) {
Car car = new Car("HW-1234", 4);
System.out.println(car.getClass().getSimpleName());
System.out.println(car.getClass().getSuperclass());
System.out.println(Vehicle.class.getSuperclass());
System.out.println("Hawler".getClass().getSuperclass());
System.out.println(Object.class.getSuperclass());
Object thing = car; // every object is an Object
System.out.println(thing instanceof Vehicle);
}
}$ java Root Car class Vehicle class java.lang.Object class java.lang.Object null true
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 54
Vehicle has no extends, so its superclass is Object.
Vehicleهیچextendsـی نییە، بۆیەObjectـە.- Lineدێڕی 56
Object is the root: it has no superclass, so null.
Objectڕەگەکەیە: هیچ نییە، بۆیەnull.
Object: the root of every classObject: ڕەگی هەموو کلاسێک
toString(): one method for the whole familytoString(): یەک میتۆد بۆ هەموو خێزانەکە
toString() comes from Object, which prints the class name and a hash code until a class overrides it (Printing an object). Override it once in Vehicle and every subclass inherits the new version. getClass().getSimpleName() gives the name of the object's real class, so one method writes Car or Bus correctly, and Bus adds its route with super.toString():
toString() لە Objectـەوە دێت کە ناوی و چاپ دەکات، تا ئەوکاتەی دووپاتە پێناسەی بکاتەوە (چاپکردنی ئۆبجێکتێک). یەک جار لە Vehicleـدا دووپاتە پێناسەی بکەرەوە و هەموو وەشانە نوێیەکە وەردەگرێت. getClass().getSimpleName() ناوی ڕاستەقینەکەی دەدات، بۆیە یەک Car یان Bus بە دروستی دەنووسێت و Bus بە super.toString() ڕێگاکەی خۆی زیاد دەکات:
import java.util.ArrayList;
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
@Override
public String toString() {
return getClass().getSimpleName() + " " + plate;
}
}
class Car extends Vehicle {
Car(String plate) {
super(plate, 5);
}
}
class Bus extends Vehicle {
String route;
Bus(String plate, int seats, String route) {
super(plate, seats);
this.route = route;
}
@Override
public String toString() {
return super.toString() + " (" + route + ")";
}
}
public class Names {
public static void main(String[] args) {
ArrayList<Vehicle> fleet = new ArrayList<>();
fleet.add(new Car("HW-1234"));
fleet.add(new Bus("DH-5678", 45, "Hawler - Duhok"));
System.out.println(fleet.get(0));
System.out.println(fleet);
}
}$ java Names Car HW-1234 [Car HW-1234, Bus DH-5678 (Hawler - Duhok)]
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 14
getClass() is the real class of the object, so this one line works for every subclass.
getClass()ڕاستەقینەکەی ، بۆیە ئەم یەک دێڕە بۆ هەموو کار دەکات.- Lineدێڕی 34
Bus's override reuses Vehicle's text.
وەشانە نوێیەکەی
BusدەقەکەیVehicleدووپاتە بەکار دەهێنێتەوە.
Object: the root of every classObject: ڕەگی هەموو کلاسێک
equals(): the same plate, the same vehicleequals(): هەمان ژمارە، هەمان ئامراز
== asks whether two references point to the same object (Two variables, one object). Object's equals() does exactly the same, so two Car objects with the plate HW-1234 are not equal, and a list's contains(), which uses equals(), cannot find the second one: that run prints false three times. Override equals(Object) to say what equal means for your class, here the same plate:
== دەپرسێت ئایا دوو ئاماژە بۆ هەمان دەکەن (دوو گۆڕاو، یەک ئۆبجێکت). equals()ـی Object ڕێک هەمان کار دەکات، بۆیە دوو Car بە ژمارەی HW-1234 یەکسان نین و contains()ـی ، کە equals() بەکار دەهێنێت، دووەمیان نادۆزێتەوە: ئەو جێبەجێکردنە سێ جار false چاپ دەکات. equals(Object) دووپاتە پێناسە بکەرەوە بۆ ئەوەی بڵێیت یەکسان بۆ چی دەگەیەنێت، لێرەدا هەمان ژمارە:
import java.util.ArrayList;
class Vehicle {
String plate;
Vehicle(String plate) {
this.plate = plate;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof Vehicle)) {
return false;
}
Vehicle v = (Vehicle) other;
return plate.equals(v.plate);
}
@Override
public int hashCode() {
return plate.hashCode();
}
}
class Car extends Vehicle {
Car(String plate) {
super(plate);
}
}
public class Same {
public static void main(String[] args) {
Car a = new Car("HW-1234");
Car b = new Car("HW-1234");
System.out.println(a == b);
System.out.println(a.equals(b));
ArrayList<Vehicle> parked = new ArrayList<>();
parked.add(a);
System.out.println(parked.contains(b));
}
}$ java Same false true true
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 11-19
The parameter is Object; instanceof also returns false for null.
Objectـە؛instanceofبۆnullـیشfalseدەگەڕێنێتەوە.- Lineدێڕی 23-24
Equal vehicles must give equal hash codes.
ئامرازە یەکسانەکان دەبێت هەمان بدەن.
Java's rule: when you override equals, override hashCode too, so that equal objects give equal hash codes. HashMap and HashSet depend on it (Your own class as a key).
یاسای Java: کاتێک equals دووپاتە پێناسە دەکەیتەوە، hashCodeـیش دووپاتە پێناسە بکەرەوە، بۆ ئەوەی یەکسان یەکسان بدەن. HashMap و HashSet پشتی پێ دەبەستن (کلاسی خۆت وەک کلیل).
Object: the root of every classObject: ڕەگی هەموو کلاسێک
Common mistake: equals(Vehicle)هەڵەی باو: equals(Vehicle)
final classes and methodsکلاسەکان و میتۆدەکانی final
final closes a door. A final class cannot be extended, and a final method cannot be overridden. Use it when a change in a subclass could break something important. String, Integer and Math are final classes, so nobody can make a fake String. (A final field, which gets its value once, is another use of the same word: final fields.)
final دەرگایەک دادەخات. final extends ناکرێت و final دووپاتە پێناسە ناکرێتەوە. بەکاری بهێنە کاتێک گۆڕانکارییەک لە لەوانەیە شتێکی گرنگ تێک بدات. String، Integer و Math finalـن، بۆیە کەس ناتوانێت Stringـێکی ساختە دروست بکات. ( final، کە تەنیا یەک جار وەردەگرێت، بەکارهێنانێکی تری هەمان وشەیە: تایبەتمەندییەکانی final.)
class Vehicle {
String plate;
int seats;
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
final class Motorbike extends Vehicle {
}
class ElectricMotorbike extends Motorbike {
}
public class Electric {
public static void main(String[] args) {
new ElectricMotorbike().describe();
}
}$ javac Electric.java
Electric.java:13: error: cannot inherit from final Motorbike
class ElectricMotorbike extends Motorbike {
^
1 errorA final method is protected the same way. final String getPlate() in Vehicle cannot be overridden in Car: getPlate() in Car cannot override getPlate() in Vehicle ... overridden method is final.
final بە هەمان شێوە پارێزراوە. final String getPlate() لە Vehicleـدا لە Carـدا دووپاتە پێناسە ناکرێتەوە: getPlate() in Car cannot override getPlate() in Vehicle ... overridden method is final.
Common mistakesهەڵە باوەکان
Every message below is the real text from javac or java 17 for the programs of this lesson.
هەموو پەیامێکی خوارەوە دەقی ڕاستەقینەی javac یان java 17ـە بۆ ئەم وانەیە.
| Mistakeهەڵە | What javac or java saysjavac یان java چی دەڵێت | Fixچارەسەر |
|---|---|---|
Two superclasses: extends Car, Busدوو : extends Car, Bus | '{' expected | Extend one class; combine abilities with interfacesلە یەک extends بکە؛ توانا بە کۆ بکەرەوە |
A subclass uses a private field of its superclass privateـی بەکار دەهێنێت | km has private access in Vehicle | Use a public or protected method of the superclass public یان protectedـی بەکار بهێنە |
A protected field from another package, not a subclass protected لە ترەوە، بێ ئەوەی بێت | plate has protected access in Vehicle | Call a public method insteadلە جیاتی ئەوە public بانگ بکە |
No super(...), and the superclass has no no-argument constructorsuper(...) نییە و بێ نییە | constructor Vehicle in class Vehicle cannot be applied to given types; required: String,int found: no arguments | Call super(plate, 5); as the first statementsuper(plate, 5); وەک یەکەم بانگ بکە |
super(...) after another statementsuper(...) دوای تر | call to super must be first statement in constructor | Move it to the first lineبیبە بۆ یەکەم دێڕ |
A typo in an override, without @Overrideهەڵەی نووسین لە ، بەبێ @Override | No error: the old describe() still runs | Write @Override on every overrideلە سەرووی هەموو @Override بنووسە |
The same typo with @Overrideهەمان هەڵەی نووسین بە @Override | method does not override or implement a method from a supertype | Fix the name or the parametersناو یان چاک بکە |
| An override with less access بە دەستڕاگەیشتنی کەمتر | describe() in Car cannot override describe() in Vehicle; attempting to assign weaker access privileges; was public | Keep the same access, or a wider oneهەمان دەستڕاگەیشتن بهێڵەوە، یان فراوانتر |
| An override with another return type بە تر | describe() in Car cannot override describe() in Vehicle; return type String is not compatible with void | Use the same return typeهەمان بەکار بهێنە |
Overriding a final methodدووپاتە پێناسەکردنەوەی final | getPlate() in Car cannot override getPlate() in Vehicle; overridden method is final | Use the method as it is وەک خۆی بەکار بهێنە |
Extending a final classextendsکردنی final | cannot inherit from final Motorbike | Use the class as it is, or hold one in a field (has-a) وەک خۆی بەکار بهێنە، یان لە هەڵیبگرە (has-a) |
| A subclass member through a superclass variableئەندامێکی لە ڕێگەی | cannot find symbol ... location: variable v of type Vehicle | Check with instanceof, then castبە instanceof بیپشکنە، پاشان جۆرەکە بگۆڕە |
| A downcast without the castگۆڕین بۆ خوارەوە بەبێ | incompatible types: Vehicle cannot be converted to Car | Write (Car) v(Car) v بنووسە |
| A downcast to the wrong classگۆڕین بۆ خوارەوە بۆ هەڵە | ClassCastException: class Car cannot be cast to class Bus | Test with instanceof firstسەرەتا بە instanceof تاقی بکەرەوە |
equals(Vehicle) instead of equals(Object)equals(Vehicle) لە جیاتی equals(Object) | No error: contains() returns false | Write equals(Object) with @Override, and hashCode() tooequals(Object) بە @Override بنووسە، hashCode()ـیش |
Practiceڕاهێنان
Write a class Shape with a method double area() that returns 0. Write Circle (a radius) and Square (a side) that extend it and override area(). Put a circle of radius 1, a square of side 2 and a circle of radius 0.5 in an ArrayList<Shape>, print each area with two decimals (Rounding) and the total.
Shape بە double area() بنووسە کە 0 بگەڕێنێتەوە. Circle (نیوەتیرە) و Square (لا) بنووسە کە لێی extends بکەن و area() دووپاتە پێناسە بکەنەوە. بازنەیەک بە نیوەتیرەی 1، چوارگۆشەیەک بە لای 2 و بازنەیەک بە نیوەتیرەی 0.5 بخەرە ناو ArrayList<Shape>، ڕووبەری هەر یەکەیان بە دوو ژمارەی دوای خاڵ (خڕکردنەوە) و کۆکەی گشتی چاپ بکە.
Hintئاماژە
Use Math.PI * radius * radius for the circle.
بۆ بازنە Math.PI * radius * radius بەکار بهێنە.
Show answerوەڵامەکە پیشان بدە
import java.util.ArrayList;
class Shape {
double area() {
return 0;
}
}
class Circle extends Shape {
double radius;
Circle(double radius) {
this.radius = radius;
}
@Override
double area() {
return Math.PI * radius * radius;
}
}
class Square extends Shape {
double side;
Square(double side) {
this.side = side;
}
@Override
double area() {
return side * side;
}
}
public class ShapeAreas {
public static void main(String[] args) {
ArrayList<Shape> shapes = new ArrayList<>();
shapes.add(new Circle(1));
shapes.add(new Square(2));
shapes.add(new Circle(0.5));
double total = 0;
for (Shape s : shapes) {
double a = Math.round(s.area() * 100) / 100.0; // two decimals
System.out.println(s.getClass().getSimpleName() + ": " + a);
total = total + s.area();
}
System.out.println("Total: " + Math.round(total * 100) / 100.0);
}
}$ java ShapeAreas Circle: 3.14 Square: 4.0 Circle: 0.79 Total: 7.93
Shape's area() returns 0, which means nothing for a shape in general. The next lesson fixes this with an abstract class (Abstract classes).
area()ـی Shape 0 دەگەڕێنێتەوە کە بۆ «شێوەیەکی گشتی» هیچ واتایەکی نییە. وانەی داهاتوو بە چاکی دەکات (کلاسە ڕووتەکان).
An Employee has a name and a monthly salary in Iraqi dinars, and monthlyPay() returns the salary. A Teacher earns 15,000 IQD more for each extra lesson, a Driver 10,000 IQD more for each trip. Override monthlyPay() in both with super.monthlyPay(), and print the pay of Lana (900,000), Soran (1,000,000, 6 extra lessons) and Karwan (700,000, 12 trips) from one ArrayList<Employee>.
Employee ناو و مووچەیەکی مانگانەی بە دیناری عێراقی هەیە و monthlyPay() مووچەکە دەگەڕێنێتەوە. Teacher بۆ هەر وانەیەکی زیادە 15000 دیناری زیاتر وەردەگرێت و Driver بۆ هەر گەشتێک 10000 دیناری زیاتر. monthlyPay() لە هەردووکیاندا بە super.monthlyPay() دووپاتە پێناسە بکەرەوە و مووچەی Lana (900000)، Soran (1000000، 6 وانەی زیادە) و Karwan (700000، 12 گەشت) لە یەک ArrayList<Employee>ـەوە چاپ بکە.
Show answerوەڵامەکە پیشان بدە
import java.util.ArrayList;
class Employee {
String name;
int salary; // Iraqi dinars per month
Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
int monthlyPay() {
return salary;
}
}
class Teacher extends Employee {
int extraLessons;
Teacher(String name, int salary, int extraLessons) {
super(name, salary);
this.extraLessons = extraLessons;
}
@Override
int monthlyPay() {
return super.monthlyPay() + extraLessons * 15000;
}
}
class Driver extends Employee {
int trips;
Driver(String name, int salary, int trips) {
super(name, salary);
this.trips = trips;
}
@Override
int monthlyPay() {
return super.monthlyPay() + trips * 10000;
}
}
public class Payroll {
public static void main(String[] args) {
ArrayList<Employee> staff = new ArrayList<>();
staff.add(new Employee("Lana", 900000));
staff.add(new Teacher("Soran", 1000000, 6));
staff.add(new Driver("Karwan", 700000, 12));
int total = 0;
for (Employee e : staff) {
System.out.println(e.name + ": " + e.monthlyPay() + " IQD");
total = total + e.monthlyPay();
}
System.out.println("Total: " + total + " IQD");
}
}$ java Payroll Lana: 900000 IQD Soran: 1090000 IQD Karwan: 820000 IQD Total: 2810000 IQD
With the Vehicle, Car, Bus and Motorbike classes of this lesson, what does this main print? Decide first, then compare with the real run.
بە Vehicle، Car، Bus و Motorbikeـی ئەم وانەیە، ئەم mainـە چی چاپ دەکات؟ سەرەتا بڕیار بدە، پاشان لەگەڵ جێبەجێکردنی ڕاستەقینەدا بەراوردی بکە.
Vehicle a = new Bus("DH-5678", 45, "Hawler - Duhok");
Vehicle b = new Motorbike("SL-9012");
a.describe();
b.describe();
System.out.println(a instanceof Car);
System.out.println(b instanceof Vehicle);
System.out.println(a.seats + b.seats);Show answerوەڵامەکە پیشان بدە
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Car extends Vehicle {
int doors;
Car(String plate, int doors) {
super(plate, 5);
this.doors = doors;
}
@Override
void describe() {
System.out.println(plate + ": a car with " + doors + " doors");
}
}
class Bus extends Vehicle {
String route;
Bus(String plate, int seats, String route) {
super(plate, seats);
this.route = route;
}
@Override
void describe() {
System.out.println(plate + ": a bus on " + route);
}
}
class Motorbike extends Vehicle {
Motorbike(String plate) {
super(plate, 2);
}
}
public class Predict {
public static void main(String[] args) {
Vehicle a = new Bus("DH-5678", 45, "Hawler - Duhok");
Vehicle b = new Motorbike("SL-9012");
a.describe();
b.describe();
System.out.println(a instanceof Car);
System.out.println(b instanceof Vehicle);
System.out.println(a.seats + b.seats);
}
}$ java Predict DH-5678: a bus on Hawler - Duhok SL-9012: 2 seats false true 47
a holds a Bus, so Bus's describe() runs; b holds a Motorbike, which uses Vehicle's version. a instanceof Car is false (a Bus is not a Car), b instanceof Vehicle is true, and .
a Busـێک هەڵدەگرێت، بۆیە describe()ـی Bus جێبەجێ دەبێت؛ b Motorbikeـێک هەڵدەگرێت کە وەشانەکەی Vehicle بەکار دەهێنێت. a instanceof Car falseـە (پاس جۆرێک نییە لە ئۆتۆمبێلی سواری)، b instanceof Vehicle trueـە و .
javac rejects this delivery motorbike twice. Read both messages and fix the class Motorbike.
javac دوو جار ئەم ماتۆڕسکیلی گەیاندنە ڕەت دەکاتەوە. هەردوو پەیامەکە بخوێنەرەوە و Motorbike چاک بکە.
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
public void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Motorbike extends Vehicle {
boolean deliveryBox;
Motorbike(String plate, boolean deliveryBox) {
this.plate = plate;
this.deliveryBox = deliveryBox;
}
void describe() {
System.out.println(plate + ": delivery box " + deliveryBox);
}
}
public class Delivery {
public static void main(String[] args) {
Vehicle v = new Motorbike("SL-9012", true);
v.describe();
}
}$ javac Delivery.java
Delivery.java:18: error: constructor Vehicle in class Vehicle cannot be applied to given types;
Motorbike(String plate, boolean deliveryBox) {
^
required: String,int
found: no arguments
reason: actual and formal argument lists differ in length
Delivery.java:23: error: describe() in Motorbike cannot override describe() in Vehicle
void describe() {
^
attempting to assign weaker access privileges; was public
2 errorsShow answerوەڵامەکە پیشان بدە
class Vehicle {
String plate;
int seats;
Vehicle(String plate, int seats) {
this.plate = plate;
this.seats = seats;
}
public void describe() {
System.out.println(plate + ": " + seats + " seats");
}
}
class Motorbike extends Vehicle {
boolean deliveryBox;
Motorbike(String plate, boolean deliveryBox) {
super(plate, 2);
this.deliveryBox = deliveryBox;
}
@Override
public void describe() {
System.out.println(plate + ": delivery box " + deliveryBox);
}
}
public class Delivery {
public static void main(String[] args) {
Vehicle v = new Motorbike("SL-9012", true);
v.describe();
}
}$ java Delivery SL-9012: delivery box true
Error 1: the constructor had no super(...), and Vehicle has no Vehicle(); call super(plate, 2); first. Error 2: describe() was public in Vehicle, so the override must be public too.
هەڵەی 1: super(...)ـی نەبوو و Vehicle هیچ Vehicle()ـێکی نییە؛ سەرەتا super(plate, 2); بانگ بکە. هەڵەی 2: describe() لە Vehicleـدا publicـە، بۆیە وەشانە نوێیەکەش دەبێت public بێت.
Two Student objects are the same student when their student numbers (id) are equal, even if the name is written differently. Override equals and hashCode, then test contains() with a new object for number 2041.
دوو Student هەمان قوتابین کاتێک ژمارەی قوتابییەکەیان (id) یەکسان بێت، تەنانەت ئەگەر ناوەکە بە شێوەیەکی تر نووسرابێت. equals و hashCode دووپاتە پێناسە بکەرەوە، پاشان contains() بە نوێ بۆ ژمارە 2041 تاقی بکەرەوە.
Show answerوەڵامەکە پیشان بدە
import java.util.ArrayList;
class Student {
int id;
String name;
Student(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof Student)) {
return false;
}
Student s = (Student) other;
return id == s.id;
}
@Override
public int hashCode() {
return Integer.hashCode(id);
}
@Override
public String toString() {
return id + " " + name;
}
}
public class Register {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
list.add(new Student(2041, "Lana"));
list.add(new Student(2042, "Rebin"));
Student again = new Student(2041, "Lana K.");
System.out.println(list.contains(again));
System.out.println(again.equals(list.get(1)));
System.out.println(list);
}
}$ java Register true false [2041 Lana, 2042 Rebin]
For each pair, choose extends (is-a) or a field (has-a): (a) Laptop and Computer, (b) Car and Engine, (c) Teacher and Employee, (d) Classroom and Student, (e) Square and Shape.
بۆ هەر جووتێک، extends (is-a) یان (has-a) هەڵبژێرە: (a) Laptop و Computer، (b) Car و Engine، (c) Teacher و Employee، (d) Classroom و Student، (e) Square و Shape.
Show answerوەڵامەکە پیشان بدە
| Pairجووت | Answerوەڵام | Whyبۆچی |
|---|---|---|
| (a) | class Laptop extends Computer | a laptop is a computer جۆرێکە لە |
| (b) | Engine engine; | a car has an engineئۆتۆمبێل بزوێنەرێکی هەیە |
| (c) | class Teacher extends Employee | a teacher is an employeeمامۆستا جۆرێکە لە فەرمانبەر |
| (d) | ArrayList<Student> students; | a classroom has studentsپۆل قوتابیی هەیە |
| (e) | class Square extends Shape | a square is a shapeچوارگۆشە جۆرێکە لە شێوە |
Summaryکورتە
class Car extends Vehicle: the subclass Car inherits the members of the superclass Vehicle; use it only when "a Car is a Vehicle" is true (otherwise a field: has-a).- One direct superclass, as many levels as needed; every chain ends at
Object. privatemembers and constructors are not inherited;protectedopens a member to subclasses.super(...)is the first statement of a subclass constructor; without it javac addssuper().- Overriding: the same signature in a subclass, marked
@Override;super.method()reuses the old version. Overloading is different: other parameters. - Polymorphism: a superclass variable may hold any subclass object; javac checks the variable type, the object's version runs.
- Upcasts are automatic; downcasts need
(Type)and aninstanceofcheck, or a ClassCastException comes. - Override
toString(), andequals(Object)together withhashCode();finalstops extending and overriding.
class Car extends Vehicle: Car ئەندامەکانی Vehicle وەردەگرێت؛ تەنیا کاتێک بەکاری بهێنە کە «Car جۆرێکە لە Vehicle» ڕاست بێت (ئەگینا : has-a).- یەک ڕاستەوخۆ، هەر چەند ئاستێک کە پێویست بێت؛ هەموو زنجیرەیەک بە
Objectکۆتایی دێت. - ئەندامە
privateـەکان و بە نادرێن؛protectedئەندامێک بۆ دەکاتەوە. super(...)یەکەم ؛ بەبێ ئەو javacsuper()زیاد دەکات.- : هەمان لە ، بە نیشانەی
@Override؛super.method()وەشانە کۆنەکە بەکار دەهێنێتەوە. جیاوازە: تر. - : دەتوانێت هەر هەڵبگرێت؛ javac جۆری دەپشکنێت و وەشانەکەی جێبەجێ دەبێت.
- گۆڕین بۆ سەرەوە خۆکارە؛ گۆڕین بۆ خوارەوە
(Type)و پشکنینیinstanceofـی دەوێت، ئەگینا ClassCastException دێت. toString()دووپاتە پێناسە بکەرەوە، هەروەهاequals(Object)لەگەڵhashCode()؛finalڕێگە لە extends و دووپاتە پێناسەکردنەوە دەگرێت.
What does a subclass not inherit?کلاسی منداڵ چی بە بۆماوە وەرناگرێت؟
Private members (it cannot name them) and constructors (it calls them with super).
ئەندامە privateـەکان (ناتوانێت ناویان بهێنێت) و (بە super بانگیان دەکات).
What is the difference between overriding and overloading?جیاوازیی پێناسەکردنەوەی میتۆد و فرەپێناسەکردنی میتۆد چییە؟
Overriding: the same signature in a subclass, chosen by the object at run time. Overloading: the same name with other parameters, chosen by javac from the arguments.
: هەمان لە ، لە کاتی جێبەجێکردندا هەڵیدەبژێرێت. : هەمان ناو بە تر، javac بەپێی هەڵیدەبژێرێت.
Vehicle v = new Bus(...); Why can you not call v.route?Vehicle v = new Bus(...); بۆچی ناتوانیت v.route بانگ بکەیت؟
javac checks the variable type Vehicle, which has no route. Check with instanceof and cast to Bus first.
javac جۆری Vehicle دەپشکنێت کە routeـی نییە. سەرەتا بە instanceof بیپشکنە و بیگۆڕە بۆ Bus.
Why override hashCode with equals?بۆچی hashCode لەگەڵ equals دووپاتە پێناسە دەکرێتەوە؟
Equal objects must have equal hash codes, or HashMap and HashSet cannot find them.
یەکسان دەبێت یەکسانیان هەبێت، ئەگینا HashMap و HashSet نایاندۆزنەوە.
Lesson complete!وانەکە تەواو بوو!
Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.
Key termsزاراوە سەرەکییەکان
Abstract Classes, Interfaces, Inner Classes and Enumsکلاسە ڕووتەکان، نێوبەستەکان، کلاسە ناوەکییەکان و ئینەمەکان
Related lecturesوانە پەیوەندیدارەکان
- Classes and Objects: Attributes and Methodsکلاسەکان و ئۆبجێکتەکان: تایبەتمەندییەکان و میتۆدەکان
- Method Overloading and Scopeفرەپێناسەکردنی میتۆد و مەودا
- ArrayList and Wrapper ClassesArrayList و کلاسە پێچەرەوەکان
- Type Casting: Widening and Narrowingگۆڕینی جۆر: فراوانکردنی جۆر و تەسککردنەوەی جۆر
- Abstract Classes, Interfaces, Inner Classes and Enumsکلاسە ڕووتەکان، نێوبەستەکان، کلاسە ناوەکییەکان و ئینەمەکان
- HashMap and HashSetHashMap و HashSet
- Dart Classes, Inheritance and Mixinsکلاسەکان، بۆماوە و میکسینەکان لە Dartـدا
- Beyond the Basic E-R Model: Recursive, Ternary and Specialised Entitiesزیاتر لە مۆدێلی قەوارە و پەیوەندیی بنەڕەتی: پەیوەندییەکانی خۆیی و سێیانی و قەوارە تایبەتکراوەکان
- Building Softwareدروستکردنی نەرمەواڵە
References and further readingسەرچاوەکان و خوێندنەوەی زیاتر
- W3Schools: Java Inheritance
- W3Schools: Java Polymorphism
- W3Schools: Java super Keyword
- dev.java: Inheritance
- dev.java: Polymorphism (also super and final classes)
- The Java Tutorials: Inheritance (casting objects)
- The Java Tutorials: Overriding and Hiding Methods
- The Java Tutorials: Polymorphism
- The Java Tutorials: Using the Keyword super
- The Java Tutorials: Object as a Superclass
- The Java Tutorials: Writing Final Classes and Methods
- Java SE 17 API: Object (equals, hashCode, toString, getClass)
- Java Language Specification (Java SE 17), chapter 8: §8.1.4 superclasses, §8.2 members, §8.4.8 overriding, §8.8.7 constructor body, §8.8.9 default constructor
- JEP 394: Pattern Matching for instanceof
- JEP 409: Sealed Classes
- JEP 513: Flexible Constructor Bodies (Java 25)
This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.