JavaRush /Java блогу /Random-KY /Javaда бир нече мурас. Курам жана мурас
DSergey_Kh
Деңгээл

Javaда бир нече мурас. Курам жана мурас

Группада жарыяланган

Javaдагы бир нече мурас

Бир нече тукум куучулук бир нече суперкласстардан мурас алган класс түзүүгө мүмкүндүк берет. C++ сыяктуу башка популярдуу an objectиге багытталган программалоо тилдеринен айырмаланып, Java класстардан бир нече мураска жол бербейт. Java бир нече класстын мурасын колдобойт, анткени ал алмаз көйгөйүнө алып келиши мүмкүн. Жана бул көйгөйдү чечүүнүн жолдорун издөөнүн ордуна, биз бир нече тукум куучулук сыяктуу эле натыйжага кантип жетүүгө боло турган жакшыраак варианттар бар.

Алмаз маселеси

Алмаз маселесин оңойраак түшүнүү үчүн, келгиле, Java-да бир нече тукум куучулук колдоого алынат деп коёлу. Бул учурда, биз төмөндөгү сүрөттө көрсөтүлгөндөй класс иерархиясына ээ болушубуз мүмкүн. Класс абстракттуу жана анда кандайдыр бир метод жарыяланды деп Javaда бир нече мурас.  Курамы жана мурастоо - 1коёлу . SuperClassБетон класстары да ClassAжана ClassB.
package com.journaldev.inheritance;
public abstract class SuperClass {
	public abstract void doSomething();
}
package com.journaldev.inheritance;
public class ClassA extends SuperClass{
	@Override
	public void doSomething(){
		System.out.println("doSomething implementation of A");
	}
	//ClassA own method
	public void methodA(){
	}
}
package com.journaldev.inheritance;
public class ClassB extends SuperClass{
	@Override
	public void doSomething(){
		System.out.println("doSomething implementation of B");
	}
	//ClassB specific method
	public void methodB(){
	}
}
ClassCЭми биз аны жанадан мураска ClassAалгыбыз келет дейли ClassB.
package com.journaldev.inheritance;
public class ClassC extends ClassA, ClassB{
	public void test(){
		//calling super class method
		doSomething();
	}
}
Метод test()суперкласс ыкмасын чакырарын эске алыңыз doSomething(). Бул бүдөмүккө алып келет, анткени компилятор кайсы суперкласс ыкмасын аткарууну билбейт. Бул алмаз көйгөйү деп аталган алмаз түрүндөгү класс диаграммасы. Бул Java бир нече мурасты колдобой турган негизги себеби болуп саналат. Жогорудагы бир нече класс тукум куучулук көйгөйү жок дегенде бир жалпы ыкмасы бар үч класста гана болушу мүмкүн экенин эске алыңыз.

Көптөгөн интерфейстик мурас

Javaда класстарда бир нече тукум куучулук колдоого алынbyte, бирок интерфейстерде колдоого алынат. Жана бир интерфейс көптөгөн башка интерфейстерди кеңейте алат. Төмөндө жөнөкөй мисал келтирилген.
package com.journaldev.inheritance;
public interface InterfaceA {
	public void doSomething();
}
package com.journaldev.inheritance;
public interface InterfaceB {
	public void doSomething();
}
Эки интерфейс тең бирдей ыкманы жарыялаганына көңүл буруңуз. Эми биз төмөндөгү мисалда көрсөтүлгөндөй, бул эки интерфейсти тең кеңейтүүчү интерфейсти түзө алабыз.
package com.journaldev.inheritance;
public interface InterfaceC extends InterfaceA, InterfaceB {
	//same method is declared in InterfaceA and InterfaceB both
	public void doSomething();
}
Бул сонун иштейт, анткени интерфейстер методдорду гана жарыялайт жана ишке ашыруу интерфейсти мурастаган класстарда аткарылат. Ошентип, бир нече интерфейс мурасында бүдөмүктүктү алуу үчүн эч кандай жол жок.
package com.journaldev.inheritance;
public class InterfacesImpl implements InterfaceA, InterfaceB, InterfaceC {
	@Override
	public void doSomething() {
		System.out.println("doSomething implementation of concrete class");
	}
	public static void main(String[] args) {
		InterfaceA objA = new InterfacesImpl();
		InterfaceB objB = new InterfacesImpl();
		InterfaceC objC = new InterfacesImpl();

		//all the method calls below are going to same concrete implementation
		objA.doSomething();
		objB.doSomething();
		objC.doSomething();
	}
}
Кайсы бир суперкласс ыкмасын жокко чыгарганда же интерфейс ыкмасын ишке ашырууда annotationны колдонуңуз @Override. methodA()Эгер класстын функциясын жана класстын ClassAфункциясын класста колдонгубуз келсе эмне болот ? Чечим курамын колдонууда жатат. Төмөндө класстын методдорун жана an objectтердин биринин ыкмасын аныктоо үчүн композицияны колдонгон класстын versionсы келтирилген .methodB()ClassBClassCClassCdoSomething()
package com.journaldev.inheritance;
public class ClassC{
	ClassA objA = new ClassA();
	ClassB objB = new ClassB();
	public void test(){
		objA.doSomething();
	}
	public void methodA(){
		objA.methodA();
	}
	public void methodB(){
		objB.methodB();
	}
}

Курам жана мурас

Java программалоонун эң жакшы практикаларынын бири - "мураска чейин курамын бекитүү". Биз бул ыкманы жактырган кээ бир аспектилерди изилдейбиз.
  1. Бизде суперкласс жана аны кеңейтүүчү класс бар дейли:

    package com.journaldev.inheritance;
    public class ClassC{
    	public void methodC(){
    	}
    }
    package com.journaldev.inheritance;
    public class ClassD extends ClassC{
    	public int test(){
    		return 0;
    	}
    }

    Жогорудагы code түзөт жана жакшы иштейт. Бирок, класстын аткарылышын ClassCтөмөндө көрсөтүлгөндөй өзгөртсөк эмне болот:

    package com.journaldev.inheritance;
    public class ClassC{
    	public void methodC(){
    	}
    	public void test(){
    	}
    }

    Метод test()субкласста мурунтан эле бар экенин эске алыңыз, бирок кайтаруу түрү башка. Эми класс ClassDкомпиляцияланbyte жана эгер сиз кандайдыр бир IDE колдонсоңуз, ал сизге суперкласста же субкласста кайтаруу түрүн өзгөртүүнү сунуштайт.

    Эми бизде көп деңгээлдүү класстын мурас иерархиясы бар жана суперкласска кирүү мүмкүнчүлүгү жок болгон жагдайды элестетиңиз. Компиляция катасын алып салуу үчүн биздин субкласс метод кол тамгасын же анын атын өзгөртүүдөн башка аргабыз жок. Ошондой эле субкласс ыкмасын ал аталган бардык жерлерде өзгөртүүгө туура келет. Ошентип, мурас биздин codeду морт кылат.

    Композицияда жогоруда айтылган көйгөй эч качан болбойт жана бул аны мурастоо үчүн жагымдуураак кылат.

  2. Мурастыктын дагы бир көйгөйү - биз кардарга суперкласстын бардык ыкмаларын ачып беребиз жана эгерде биздин суперкласс туура иштелип чыкпаса жана коопсуздук тешиктери бар болсо, анда классыбыздын эң жакшы ишке ашырылышын ишке ашырганыбыз менен, биз начар ишке ашырууга таасир этебиз. суперкласстын. Композиция бизге суперкласстын методдоруна башкарылуучу жеткorкти камсыз кылууга жардам берет, ал эми мурастоо суперкласстын ыкмаларын көзөмөлдөөнү камсыз кылbyte. Бул да тукум куучулуктан композициянын негизги артыкчылыктарынын бири.

  3. Композициянын дагы бир артыкчылыгы - бул чакыруу ыкмаларында ийкемдүүлүккө мүмкүндүк берет. Биздин жогоруда берилген классты ишке ашыруу ClassCоптималдуу эмес жана компиляция убактысы чакырыла турган ыкмага байланганын камсыздайт. Минималдуу өзгөртүүлөр менен биз чалуу ыкмасын ийкемдүү жана динамикалык кыла алабыз.

    package com.journaldev.inheritance;
    public class ClassC{
    	SuperClass obj = null;
    	public ClassC(SuperClass o){
    		this.obj = o;
    	}
    	public void test(){
    		obj.doSomething();
    	}
    	public static void main(String args[]){
    		ClassC obj1 = new ClassC(new ClassA());
    		ClassC obj2 = new ClassC(new ClassB());
    
    		obj1.test();
    		obj2.test();
    	}
    }

    Жогоруда көрсөтүлгөн программанын натыйжасы:

    doSomething implementation of A
    doSomething implementation of B

    Методду чакыруудагы бул ийкемдүүлүк мурастоодо жок, бул композицияны тандоого дагы бир пайда кошот.

  4. Композиция менен бирдикти тестирлөө оңой, анткени биз суперкласстын бардык ыкмаларын колдонуп жатканыбызды билебиз жана аларды тестке көчүрө алабыз. Ал эми мураста биз суперкласска көбүрөөк көз карандыбыз жана суперкласстын колдонула турган бардык ыкмаларын билбейбиз. Ошентип, биз суперкласстын бардык ыкмаларын сынап көрүшүбүз керек, бул мураска байланыштуу кошумча жумуш.

    Идеалында, биз мурасты субкласс менен суперкласстын мамилеси "болот" деп аныкталганда гана колдонушубуз керек. Бардык башка учурларда, курамын колдонуу сунушталат.

Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION