हालाँकि, इस पोस्ट में पहले से ही Polymorphism को बहुत अच्छी तरह से समझाया गया है, लेकिन मैं इस बात पर अधिक जोर देना चाहूँगा कि इसका हिस्सा क्यों है।
क्यों किसी भी OOP भाषा में बहुरूपता इतना महत्वपूर्ण है।
आइए इनहेरिटेंस / पॉलीमॉर्फिज्म के साथ और बिना टीवी के लिए एक सरल एप्लिकेशन बनाने का प्रयास करें। आवेदन के प्रत्येक संस्करण को पोस्ट करें, हम एक छोटे पूर्वव्यापी करते हैं।
मान लीजिए, आप एक टीवी कंपनी में सॉफ्टवेयर इंजीनियर हैं और आपसे यूजर कमांड पर उनके मूल्यों को बढ़ाने और घटाने के लिए वॉल्यूम, ब्राइटनेस और कलर कंट्रोलर्स के लिए सॉफ्टवेयर लिखने के लिए कहा जाता है।
आप जोड़कर इन सुविधाओं में से प्रत्येक के लिए लेखन कक्षाएं शुरू करते हैं
- सेट: - नियंत्रक का मान सेट करने के लिए। (मान लीजिए कि इसमें नियंत्रक विशिष्ट कोड है)
- get: - नियंत्रक का मान प्राप्त करने के लिए। (मान लीजिए कि इसमें नियंत्रक विशिष्ट कोड है)
- समायोजित करें: - इनपुट को मान्य करने के लिए और एक नियंत्रक स्थापित करने के लिए। (सामान्य सत्यापन .. नियंत्रक से स्वतंत्र)
- कंट्रोलर के साथ यूजर इनपुट मैपिंग: - यूजर इनपुट प्राप्त करने के लिए और तदनुसार नियंत्रकों को लागू करने के लिए।
अनुप्रयोग संस्करण 1
import java.util.Scanner;
class VolumeControllerV1 {
private int value;
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of VolumeController \t"+this.value);
this.value = value;
System.out.println("New value of VolumeController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class BrightnessControllerV1 {
private int value;
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of BrightnessController \t"+this.value);
this.value = value;
System.out.println("New value of BrightnessController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class ColourControllerV1 {
private int value;
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of ColourController \t"+this.value);
this.value = value;
System.out.println("New value of ColourController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
/*
* There can be n number of controllers
* */
public class TvApplicationV1 {
public static void main(String[] args) {
VolumeControllerV1 volumeControllerV1 = new VolumeControllerV1();
BrightnessControllerV1 brightnessControllerV1 = new BrightnessControllerV1();
ColourControllerV1 colourControllerV1 = new ColourControllerV1();
OUTER: while(true) {
Scanner sc=new Scanner(System.in);
System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
System.out.println("Press any other Button to shutdown");
int button = sc.nextInt();
switch (button) {
case 1: {
volumeControllerV1.adjust(5);
break;
}
case 2: {
volumeControllerV1.adjust(-5);
break;
}
case 3: {
brightnessControllerV1.adjust(5);
break;
}
case 4: {
brightnessControllerV1.adjust(-5);
break;
}
case 5: {
colourControllerV1.adjust(5);
break;
}
case 6: {
colourControllerV1.adjust(-5);
break;
}
default:
System.out.println("Shutting down...........");
break OUTER;
}
}
}
}
अब आपके पास काम करने के लिए तैयार किया गया हमारा पहला संस्करण है। अब तक किए गए कार्य का विश्लेषण करने का समय।
टीवी अनुप्रयोग संस्करण 1 में समस्याएँ
- तीनों वर्गों में समायोजन (इंट वैल्यू) कोड डुप्लिकेट है। आप कोड डुप्लिकेट को कम करना चाहेंगे। (लेकिन आपने कॉमन कोड के बारे में नहीं सोचा और डुप्लिकेट कोड से बचने के लिए इसे किसी सुपर क्लास में ले गए)
जब तक आपका एप्लिकेशन उम्मीद के मुताबिक काम करता है, तब तक आप उसके साथ रहने का फैसला करते हैं।
कभी-कभी, आपका बॉस आपके पास वापस आ जाता है और आपसे मौजूदा एप्लिकेशन में रीसेट कार्यक्षमता जोड़ने के लिए कहता है। रीसेट सभी 3 तीन नियंत्रक को उनके संबंधित डिफ़ॉल्ट मानों पर सेट करेगा।
आप नई कार्यक्षमता के लिए एक नया वर्ग (ResetFunctionV2) लिखना शुरू करते हैं और इस नई सुविधा के लिए उपयोगकर्ता इनपुट मैपिंग कोड को मैप करते हैं।
अनुप्रयोग संस्करण 2
import java.util.Scanner;
class VolumeControllerV2 {
private int defaultValue = 25;
private int value;
int getDefaultValue() {
return defaultValue;
}
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of VolumeController \t"+this.value);
this.value = value;
System.out.println("New value of VolumeController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class BrightnessControllerV2 {
private int defaultValue = 50;
private int value;
int get() {
return value;
}
int getDefaultValue() {
return defaultValue;
}
void set(int value) {
System.out.println("Old value of BrightnessController \t"+this.value);
this.value = value;
System.out.println("New value of BrightnessController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class ColourControllerV2 {
private int defaultValue = 40;
private int value;
int get() {
return value;
}
int getDefaultValue() {
return defaultValue;
}
void set(int value) {
System.out.println("Old value of ColourController \t"+this.value);
this.value = value;
System.out.println("New value of ColourController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class ResetFunctionV2 {
private VolumeControllerV2 volumeControllerV2 ;
private BrightnessControllerV2 brightnessControllerV2;
private ColourControllerV2 colourControllerV2;
ResetFunctionV2(VolumeControllerV2 volumeControllerV2, BrightnessControllerV2 brightnessControllerV2, ColourControllerV2 colourControllerV2) {
this.volumeControllerV2 = volumeControllerV2;
this.brightnessControllerV2 = brightnessControllerV2;
this.colourControllerV2 = colourControllerV2;
}
void onReset() {
volumeControllerV2.set(volumeControllerV2.getDefaultValue());
brightnessControllerV2.set(brightnessControllerV2.getDefaultValue());
colourControllerV2.set(colourControllerV2.getDefaultValue());
}
}
/*
* so on
* There can be n number of controllers
*
* */
public class TvApplicationV2 {
public static void main(String[] args) {
VolumeControllerV2 volumeControllerV2 = new VolumeControllerV2();
BrightnessControllerV2 brightnessControllerV2 = new BrightnessControllerV2();
ColourControllerV2 colourControllerV2 = new ColourControllerV2();
ResetFunctionV2 resetFunctionV2 = new ResetFunctionV2(volumeControllerV2, brightnessControllerV2, colourControllerV2);
OUTER: while(true) {
Scanner sc=new Scanner(System.in);
System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
int button = sc.nextInt();
switch (button) {
case 1: {
volumeControllerV2.adjust(5);
break;
}
case 2: {
volumeControllerV2.adjust(-5);
break;
}
case 3: {
brightnessControllerV2.adjust(5);
break;
}
case 4: {
brightnessControllerV2.adjust(-5);
break;
}
case 5: {
colourControllerV2.adjust(5);
break;
}
case 6: {
colourControllerV2.adjust(-5);
break;
}
case 7: {
resetFunctionV2.onReset();
break;
}
default:
System.out.println("Shutting down...........");
break OUTER;
}
}
}
}
तो आप अपने आवेदन रीसेट सुविधा के साथ तैयार है। लेकिन, अब आपको यह एहसास होने लगा है
टीवी अनुप्रयोग संस्करण 2 में समस्याएँ
- यदि उत्पाद के लिए एक नया नियंत्रक पेश किया जाता है, तो आपको रीसेट सुविधा कोड बदलना होगा।
- यदि नियंत्रक की गिनती बहुत अधिक बढ़ जाती है, तो आपको नियंत्रकों के संदर्भों को रखने में समस्या होगी।
- रिसेट फीचर कोड को सभी कंट्रोलर्स क्लास के कोड (डिफ़ॉल्ट मान प्राप्त करने और सेट करने के लिए) के साथ कसकर जोड़ा जाता है।
- रीसेट सुविधा वर्ग (ResetFunctionV2) नियंत्रक वर्ग के अन्य तरीके (समायोजन) तक पहुंच सकता है जो अवांछनीय है।
उसी समय, आप बॉस से सुनते हैं कि आपको स्टार्ट-अप पर प्रत्येक कंट्रोलर, जिसमें इंटरनेट के माध्यम से कंपनी के होस्ट किए गए ड्राइवर रिपॉजिटरी से ड्राइवर के नवीनतम संस्करण की जाँच करने की आवश्यकता है, एक फीचर जोड़ना होगा।
अब आप यह सोचना शुरू करते हैं कि यह नया फीचर रिसेट फीचर से मिलता जुलता है और एप्लीकेशन (V2) के इश्यू कई गुना हो जाएंगे, यदि आप अपने एप्लिकेशन को दोबारा नहीं लगाते हैं।
आप विरासत का उपयोग करने के बारे में सोचना शुरू करते हैं ताकि आप JAVA की बहुरूपी क्षमता का लाभ उठा सकें और आप एक नया सार वर्ग (कंट्रोलर 3) जोड़ दें
- प्राप्त और निर्धारित विधि के हस्ताक्षर की घोषणा करें।
- कंटेनर को लागू करने की विधि को समायोजित करें जो पहले सभी नियंत्रकों के बीच दोहराया गया था।
- सेटलेफ़ॉल्ट विधि को घोषित करें ताकि रीसेट सुविधा को पॉलीमॉर्फिज़्म का लाभ उठाकर आसानी से लागू किया जा सके।
इन सुधारों के साथ, आपके पास आपके टीवी एप्लिकेशन का संस्करण 3 आपके साथ तैयार है।
अनुप्रयोग संस्करण 3
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
abstract class ControllerV3 {
abstract void set(int value);
abstract int get();
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
abstract void setDefault();
}
class VolumeControllerV3 extends ControllerV3 {
private int defaultValue = 25;
private int value;
public void setDefault() {
set(defaultValue);
}
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of VolumeController \t"+this.value);
this.value = value;
System.out.println("New value of VolumeController \t"+this.value);
}
}
class BrightnessControllerV3 extends ControllerV3 {
private int defaultValue = 50;
private int value;
public void setDefault() {
set(defaultValue);
}
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of BrightnessController \t"+this.value);
this.value = value;
System.out.println("New value of BrightnessController \t"+this.value);
}
}
class ColourControllerV3 extends ControllerV3 {
private int defaultValue = 40;
private int value;
public void setDefault() {
set(defaultValue);
}
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of ColourController \t"+this.value);
this.value = value;
System.out.println("New value of ColourController \t"+this.value);
}
}
class ResetFunctionV3 {
private List<ControllerV3> controllers = null;
ResetFunctionV3(List<ControllerV3> controllers) {
this.controllers = controllers;
}
void onReset() {
for (ControllerV3 controllerV3 :this.controllers) {
controllerV3.setDefault();
}
}
}
/*
* so on
* There can be n number of controllers
*
* */
public class TvApplicationV3 {
public static void main(String[] args) {
VolumeControllerV3 volumeControllerV3 = new VolumeControllerV3();
BrightnessControllerV3 brightnessControllerV3 = new BrightnessControllerV3();
ColourControllerV3 colourControllerV3 = new ColourControllerV3();
List<ControllerV3> controllerV3s = new ArrayList<>();
controllerV3s.add(volumeControllerV3);
controllerV3s.add(brightnessControllerV3);
controllerV3s.add(colourControllerV3);
ResetFunctionV3 resetFunctionV3 = new ResetFunctionV3(controllerV3s);
OUTER: while(true) {
Scanner sc=new Scanner(System.in);
System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
int button = sc.nextInt();
switch (button) {
case 1: {
volumeControllerV3.adjust(5);
break;
}
case 2: {
volumeControllerV3.adjust(-5);
break;
}
case 3: {
brightnessControllerV3.adjust(5);
break;
}
case 4: {
brightnessControllerV3.adjust(-5);
break;
}
case 5: {
colourControllerV3.adjust(5);
break;
}
case 6: {
colourControllerV3.adjust(-5);
break;
}
case 7: {
resetFunctionV3.onReset();
break;
}
default:
System.out.println("Shutting down...........");
break OUTER;
}
}
}
}
हालाँकि V2 के अंक सूची में सूचीबद्ध अधिकांश मुद्दे को छोड़कर संबोधित किया गया था
टीवी अनुप्रयोग संस्करण 3 में समस्याएँ
- रीसेट सुविधा वर्ग (ResetFunctionV3) नियंत्रक वर्ग के अन्य तरीके (समायोजन) तक पहुंच सकता है जो अवांछनीय है।
फिर, आप इस समस्या को हल करने के बारे में सोचते हैं, क्योंकि अब आपके पास एक और विशेषता है (स्टार्टअप पर ड्राइवर अपडेट) के रूप में अच्छी तरह से लागू करने के लिए। यदि आप इसे ठीक नहीं करते हैं, तो यह नई सुविधाओं के लिए भी दोहराया जाएगा।
तो आप सार वर्ग में परिभाषित अनुबंध को विभाजित करते हैं और इसके लिए 2 इंटरफेस लिखते हैं
- सुविधा रीसेट करें।
- ड्राइवर अपडेट।
और अपने 1 ठोस वर्ग को नीचे के रूप में लागू करें
अनुप्रयोग संस्करण 4
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
interface OnReset {
void setDefault();
}
interface OnStart {
void checkForDriverUpdate();
}
abstract class ControllerV4 implements OnReset,OnStart {
abstract void set(int value);
abstract int get();
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class VolumeControllerV4 extends ControllerV4 {
private int defaultValue = 25;
private int value;
@Override
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of VolumeController \t"+this.value);
this.value = value;
System.out.println("New value of VolumeController \t"+this.value);
}
@Override
public void setDefault() {
set(defaultValue);
}
@Override
public void checkForDriverUpdate() {
System.out.println("Checking driver update for VolumeController .... Done");
}
}
class BrightnessControllerV4 extends ControllerV4 {
private int defaultValue = 50;
private int value;
@Override
int get() {
return value;
}
@Override
void set(int value) {
System.out.println("Old value of BrightnessController \t"+this.value);
this.value = value;
System.out.println("New value of BrightnessController \t"+this.value);
}
@Override
public void setDefault() {
set(defaultValue);
}
@Override
public void checkForDriverUpdate() {
System.out.println("Checking driver update for BrightnessController .... Done");
}
}
class ColourControllerV4 extends ControllerV4 {
private int defaultValue = 40;
private int value;
@Override
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of ColourController \t"+this.value);
this.value = value;
System.out.println("New value of ColourController \t"+this.value);
}
@Override
public void setDefault() {
set(defaultValue);
}
@Override
public void checkForDriverUpdate() {
System.out.println("Checking driver update for ColourController .... Done");
}
}
class ResetFunctionV4 {
private List<OnReset> controllers = null;
ResetFunctionV4(List<OnReset> controllers) {
this.controllers = controllers;
}
void onReset() {
for (OnReset onreset :this.controllers) {
onreset.setDefault();
}
}
}
class InitializeDeviceV4 {
private List<OnStart> controllers = null;
InitializeDeviceV4(List<OnStart> controllers) {
this.controllers = controllers;
}
void initialize() {
for (OnStart onStart :this.controllers) {
onStart.checkForDriverUpdate();
}
}
}
/*
* so on
* There can be n number of controllers
*
* */
public class TvApplicationV4 {
public static void main(String[] args) {
VolumeControllerV4 volumeControllerV4 = new VolumeControllerV4();
BrightnessControllerV4 brightnessControllerV4 = new BrightnessControllerV4();
ColourControllerV4 colourControllerV4 = new ColourControllerV4();
List<ControllerV4> controllerV4s = new ArrayList<>();
controllerV4s.add(brightnessControllerV4);
controllerV4s.add(volumeControllerV4);
controllerV4s.add(colourControllerV4);
List<OnStart> controllersToInitialize = new ArrayList<>();
controllersToInitialize.addAll(controllerV4s);
InitializeDeviceV4 initializeDeviceV4 = new InitializeDeviceV4(controllersToInitialize);
initializeDeviceV4.initialize();
List<OnReset> controllersToReset = new ArrayList<>();
controllersToReset.addAll(controllerV4s);
ResetFunctionV4 resetFunctionV4 = new ResetFunctionV4(controllersToReset);
OUTER: while(true) {
Scanner sc=new Scanner(System.in);
System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
int button = sc.nextInt();
switch (button) {
case 1: {
volumeControllerV4.adjust(5);
break;
}
case 2: {
volumeControllerV4.adjust(-5);
break;
}
case 3: {
brightnessControllerV4.adjust(5);
break;
}
case 4: {
brightnessControllerV4.adjust(-5);
break;
}
case 5: {
colourControllerV4.adjust(5);
break;
}
case 6: {
colourControllerV4.adjust(-5);
break;
}
case 7: {
resetFunctionV4.onReset();
break;
}
default:
System.out.println("Shutting down...........");
break OUTER;
}
}
}
}
अब आपके द्वारा सामना किए गए सभी मुद्दे को संबोधित किया गया और आपने महसूस किया कि विरासत और बहुरूपता के उपयोग के साथ आप कर सकते हैं
- एप्लिकेशन के विभिन्न भाग को शिथिल रखें। (रीसेट या ड्राइवर अपडेट सुविधा घटकों को वास्तविक नियंत्रक कक्षाओं (वॉल्यूम, चमक और रंग) से अवगत कराने की आवश्यकता नहीं है, ओनेसेट या ऑनस्टार्ट को लागू करने वाला कोई भी वर्ग रीसेट या ग्राहक सुविधा के लिए स्वीकार्य होगा। घटक क्रमशः)।
- एप्लिकेशन एन्हांसमेंट आसान हो जाता है! (कंट्रोलर वॉन्ट इफ़ेक्ट रिसेट या ड्राइवर अपडेट फ़ीचर घटक का नया जोड़, और अब आपके लिए नया जोड़ना आसान है)
- अमूर्तता की परत रखें। (अब रीसेट सुविधा केवल नियंत्रकों की सेटफॉल्ट पद्धति देख सकती है और रीसेट सुविधा केवल जांचकर्ताओं की नियंत्रक विधि को देख सकती है)
उम्मीद है की यह मदद करेगा :-)