MATLAB Language
ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग
खोज…
एक वर्ग को परिभाषित करना
क्लास के समान नाम वाली .m
फ़ाइल में classdef
का उपयोग करके एक क्लास को परिभाषित किया जा सकता है। फ़ाइल में classdef
हो सकता है ... वर्ग विधियों के भीतर उपयोग के लिए end
ब्लॉक और स्थानीय फ़ंक्शन।
सबसे सामान्य MATLAB वर्ग परिभाषा में निम्नलिखित संरचना है:
classdef (ClassAttribute = expression, ...) ClassName < ParentClass1 & ParentClass2 & ...
properties (PropertyAttributes)
PropertyName
end
methods (MethodAttributes)
function obj = methodName(obj,arg2,...)
...
end
end
events (EventAttributes)
EventName
end
enumeration
EnumName
end
end
MATLAB प्रलेखन: वर्ग गुण , संपत्ति विशेषताएँ , विधि विशेषताएँ , घटना विशेषताएँ , गणना कक्षा प्रतिबंध ।
उदाहरण वर्ग:
कहा जाता है एक वर्ग Car
फाइल में परिभाषित किया जा सकता है Car.m
के रूप में
classdef Car < handle % handle class so properties persist
properties
make
model
mileage = 0;
end
methods
function obj = Car(make, model)
obj.make = make;
obj.model = model;
end
function drive(obj, milesDriven)
obj.mileage = obj.mileage + milesDriven;
end
end
end
ध्यान दें कि कंस्ट्रक्टर कक्षा के समान नाम के साथ एक विधि है। <एक निर्माता ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में एक वर्ग या संरचना का एक विशेष तरीका है जो उस प्रकार के ऑब्जेक्ट को इनिशियलाइज़ करता है। एक कंस्ट्रक्टर एक आवृत्ति विधि है, जिसमें आमतौर पर कक्षा के समान नाम होता है, और इसका उपयोग किसी वस्तु के सदस्यों के मूल्यों को निर्धारित करने के लिए किया जा सकता है, या तो डिफ़ॉल्ट रूप से या उपयोगकर्ता द्वारा परिभाषित मानों के लिए।>
इस वर्ग का एक उदाहरण कंस्ट्रक्टर को कॉल करके बनाया जा सकता है;
>> myCar = Car('Ford', 'Mustang'); //creating an instance of car class
drive
विधि को कॉल करने से माइलेज बढ़ेगा
>> myCar.mileage
ans =
0
>> myCar.drive(450);
>> myCar.mileage
ans =
450
मूल्य बनाम हैंडल कक्षाएं
MATLAB में कक्षाएं दो प्रमुख श्रेणियों में विभाजित हैं: मूल्य वर्ग और हैंडल कक्षाएं। प्रमुख अंतर यह है कि जब मूल्य वर्ग के उदाहरण को कॉपी किया जाता है, तो अंतर्निहित डेटा को नए इंस्टेंस पर कॉपी किया जाता है, जबकि हैंडल क्लासेस के लिए नया इंस्टेंस मूल डेटा को इंगित करता है और नए इंस्टेंस में बदलते मान उन्हें मूल में बदलता है। एक वर्ग को handle
क्लास से विरासत में मिला एक हैंडल के रूप में परिभाषित किया जा सकता है।
classdef valueClass
properties
data
end
end
तथा
classdef handleClass < handle
properties
data
end
end
फिर
>> v1 = valueClass;
>> v1.data = 5;
>> v2 = v1;
>> v2.data = 7;
>> v1.data
ans =
5
>> h1 = handleClass;
>> h1.data = 5;
>> h2 = h1;
>> h2.data = 7;
>> h1.data
ans =
7
कक्षाओं और अमूर्त कक्षाओं से इनहेरिट करना
अस्वीकरण: यहां प्रस्तुत उदाहरण केवल अमूर्त वर्गों और विरासत के उपयोग को दिखाने के उद्देश्य से हैं और जरूरी नहीं कि यह एक व्यावहारिक उपयोग हो। इसके अलावा, MATLAB में बहुरूपता के रूप में कोई चीज नहीं है और इसलिए अमूर्त वर्गों का उपयोग सीमित है। यह उदाहरण यह दिखाना है कि एक वर्ग को किसने बनाया है, दूसरे वर्ग से विरासत में मिला है और एक सामान्य इंटरफ़ेस को परिभाषित करने के लिए एक अमूर्त वर्ग को लागू करता है।
सार कक्षाओं का उपयोग MATLAB में सीमित है, लेकिन यह अभी भी कुछ अवसरों पर उपयोगी हो सकता है।
मान लें कि हम एक संदेश लकड़हारा चाहते हैं। हम नीचे एक के समान एक क्लास बना सकते हैं:
classdef ScreenLogger
properties(Access=protected)
scrh;
end
methods
function obj = ScreenLogger(screenhandler)
obj.scrh = screenhandler;
end
function LogMessage(obj, varargin)
if ~isempty(varargin)
varargin{1} = num2str(varargin{1});
fprintf(obj.scrh, '%s\n', sprintf(varargin{:}));
end
end
end
end
गुण और विधियाँ
संक्षेप में, गुण एक वस्तु की एक स्थिति रखते हैं, जबकि विधियाँ इंटरफ़ेस की तरह होती हैं और वस्तुओं पर क्रियाओं को परिभाषित करती हैं।
प्रॉपर्टी scrh
सुरक्षित है। यही कारण है कि इसे एक निर्माता में आरंभीकृत किया जाना चाहिए। इस संपत्ति को एक्सेस करने के लिए अन्य तरीके (गेटर्स) हैं लेकिन यह इस उदाहरण के सामना से बाहर है। गुण और विधियों को एक चर के माध्यम से एक्सेस किया जा सकता है जो किसी विधि या संपत्ति के नाम के बाद डॉट नोटेशन का उपयोग करके किसी ऑब्जेक्ट का संदर्भ रखता है:
mylogger = ScreenLogger(1); % OK
mylogger.LogMessage('My %s %d message', 'very', 1); % OK
mylogger.scrh = 2; % ERROR!!! Access denied
गुण और विधियाँ सार्वजनिक, निजी या संरक्षित हो सकती हैं। इस मामले में, संरक्षित का मतलब है कि मैं विरासत में वर्ग से बाहर तक पहुँचने में सक्षम हो scrh
लेकिन बाहर से नहीं। डिफ़ॉल्ट रूप से सभी गुण और विधियाँ सार्वजनिक हैं। इसलिए LogMessage()
को स्वतंत्र रूप से वर्ग परिभाषा के बाहर उपयोग किया जा सकता है। इसके अलावा LogMessage
एक इंटरफ़ेस को परिभाषित करता है जिसका अर्थ है कि हमें तब कॉल करना चाहिए जब हम अपने कस्टम संदेशों को लॉग करने के लिए ऑब्जेक्ट चाहते हैं।
आवेदन
मान लीजिए कि मेरे पास एक स्क्रिप्ट है जहां मैं अपने लकड़हारे का उपयोग करता हूं:
clc;
% ... a code
logger = ScreenLogger(1);
% ... a code
logger.LogMessage('something');
% ... a code
logger.LogMessage('something');
% ... a code
logger.LogMessage('something');
% ... a code
logger.LogMessage('something');
यदि मेरे पास कई स्थान हैं जहां मैं एक ही लकड़हारे का उपयोग करता हूं और फिर इसे कुछ और परिष्कृत करने के लिए बदलना चाहता हूं, जैसे कि एक फ़ाइल में एक संदेश लिखना, मुझे एक और ऑब्जेक्ट बनाना होगा:
classdef DeepLogger
properties(SetAccess=protected)
FileName
end
methods
function obj = DeepLogger(filename)
obj.FileName = filename;
end
function LogMessage(obj, varargin)
if ~isempty(varargin)
varargin{1} = num2str(varargin{1});
fid = fopen(obj.fullfname, 'a+t');
fprintf(fid, '%s\n', sprintf(varargin{:}));
fclose(fid);
end
end
end
end
और बस एक कोड की एक पंक्ति को इस में बदलें:
clc;
% ... a code
logger = DeepLogger('mymessages.log');
उपरोक्त विधि बस एक फ़ाइल खोलेगी, फ़ाइल के अंत में एक संदेश संलग्न करें और इसे बंद करें। फिलहाल, अपने इंटरफ़ेस के अनुरूप होने के लिए, मुझे याद रखना होगा कि एक विधि का नाम LogMessage()
लेकिन यह समान रूप से कुछ और भी हो सकता है। MATLAB अमूर्त वर्गों का उपयोग करके एक ही नाम पर छड़ी करने के लिए विकासशील को मजबूर कर सकता है। मान लें कि हम किसी भी लकड़हारे के लिए एक सामान्य इंटरफ़ेस परिभाषित करते हैं:
classdef MessageLogger
methods(Abstract=true)
LogMessage(obj, varargin);
end
end
अब, यदि ScreenLogger
और DeepLogger
दोनों को इस वर्ग से विरासत में मिला है, तो LogMessage()
परिभाषित नहीं होने पर MATLAB एक त्रुटि उत्पन्न करेगा। अमूर्त कक्षाएं समान कक्षाएं बनाने में मदद करती हैं जो समान इंटरफ़ेस का उपयोग कर सकती हैं।
इस निर्वासन के लिए, मैं थोड़ा अलग बदलाव करूंगा। मैं यह मानकर चल रहा हूं कि दीपलॉगर एक स्क्रीन पर लॉगिंग संदेश और एक ही समय में एक फ़ाइल में दोनों करेगा। क्योंकि ScreenLogger
स्क्रीन पर पहले से ही संदेश लॉग करता है, मैं ScreenLoggger
से बचने के लिए DeepLogger
से DeepLogger
को इनहेरिट करने जा रहा हूं। ScreenLogger
पहली पंक्ति से अलग नहीं बदलता है:
classdef ScreenLogger < MessageLogger
// the rest of previous code
हालाँकि, DeepLogger
को LogMessage
मेथड में और बदलाव की आवश्यकता है:
classdef DeepLogger < MessageLogger & ScreenLogger
properties(SetAccess=protected)
FileName
Path
end
methods
function obj = DeepLogger(screenhandler, filename)
[path,filen,ext] = fileparts(filename);
obj.FileName = [filen ext];
pbj.Path = pathn;
obj = obj@ScreenLogger(screenhandler);
end
function LogMessage(obj, varargin)
if ~isempty(varargin)
varargin{1} = num2str(varargin{1});
LogMessage@ScreenLogger(obj, varargin{:});
fid = fopen(obj.fullfname, 'a+t');
fprintf(fid, '%s\n', sprintf(varargin{:}));
fclose(fid);
end
end
end
end
सबसे पहले, मैं बस कंस्ट्रक्टर में गुणों को इनिशियलाइज़ करता हूँ। दूसरी बात, क्योंकि यह वर्ग ScreenLogger
से विरासत में मिला है ScreenLogger
मुझे इस पेरेन्ट ऑब्जेक्ट को भी इनिशियलाइज़ करना है। यह पंक्ति और भी महत्वपूर्ण है क्योंकि ScreenLogger
निर्माता को अपनी स्वयं की वस्तु को शुद्ध करने के लिए एक पैरामीटर की आवश्यकता होती है। यह रेखा:
obj = obj@ScreenLogger(screenhandler);
बस कहते हैं, "ScreenLogger के कंस्ट्रक्टर को कॉल करें और इसे स्क्रीन हैंडलर के साथ निष्क्रिय करें"। यहां यह ध्यान देने योग्य है कि मैंने scrh
को संरक्षित के रूप में परिभाषित किया है। इसलिए, मैं DeepLogger
से इस संपत्ति का समान रूप से उपयोग कर सकता DeepLogger
। यदि संपत्ति को निजी के रूप में परिभाषित किया गया था। इसे ठीक करने का एकमात्र तरीका है कंसीलर का उपयोग करना।
एक और बदलाव खंड methods
। पुनरावृत्ति से बचने के लिए, मैं एक स्क्रीन पर एक संदेश लॉग करने के लिए एक मूल वर्ग से LogMessage()
हूं। अगर मुझे स्क्रीन लॉगिंग में सुधार करने के लिए कुछ भी बदलना पड़ा, तो अब मुझे इसे एक जगह करना होगा। बाकी कोड वही है जो DeepLogger
का एक हिस्सा है।
क्योंकि यह वर्ग एक अमूर्त वर्ग से भी प्राप्त होता है MessageLogger
मुझे यह सुनिश्चित करना था कि LogMessage()
अंदर DeepLogger
LogMessage()
को भी परिभाषित किया गया है। MessageLogger
से इनहेरिट करना यहाँ थोड़ा मुश्किल है। मुझे लगता है कि यह LogMessage
फिर से परिभाषित करने के मामलों को अनिवार्य करता है - मेरा अनुमान है।
कोड के संदर्भ में जहां एक लकड़हारा लगाया जाता है, कक्षाओं में एक सामान्य इंटरफ़ेस के लिए धन्यवाद, मैं आराम कर सकता हूं ताकि पूरे कोड में यह एक पंक्ति किसी भी मुद्दे को न बना सके। पहले की तरह ही मैसेज स्क्रीन पर लॉग इन होंगे लेकिन इसके अलावा कोड एक फाइल में ऐसे मैसेज लिख देगा।
clc;
% ... a code
logger = DeepLogger(1, 'mylogfile.log');
% ... a code
logger.LogMessage('something');
% ... a code
logger.LogMessage('something');
% ... a code
logger.LogMessage('something');
% ... a code
logger.LogMessage('something');
मुझे आशा है कि इन उदाहरणों ने कक्षाओं के उपयोग, विरासत के उपयोग और अमूर्त वर्गों के उपयोग के बारे में बताया।
पुनश्च। उपरोक्त समस्या का समाधान कई में से एक है। एक अन्य समाधान, कम जटिल, ScreenLoger
को किसी अन्य FileLogger
जैसे कि FileLogger
आदि का एक घटक बनाने के लिए होगा। ScreenLogger
गुणों में से एक में आयोजित किया जाएगा। इसका LogMessage
बस LogMessage
के LogMessage
को कॉल ScreenLogger
और एक स्क्रीन पर टेक्स्ट दिखाएगा। मैंने यह दिखाने के लिए अधिक जटिल दृष्टिकोण चुना है कि मैटलैब में कक्षाएं कैसे काम करती हैं। नीचे दिए गए उदाहरण कोड:
classdef DeepLogger < MessageLogger
properties(SetAccess=protected)
FileName
Path
ScrLogger
end
methods
function obj = DeepLogger(screenhandler, filename)
[path,filen,ext] = fileparts(filename);
obj.FileName = [filen ext];
obj.Path = pathn;
obj.ScrLogger = ScreenLogger(screenhandler);
end
function LogMessage(obj, varargin)
if ~isempty(varargin)
varargin{1} = num2str(varargin{1});
obj.LogMessage(obj.ScrLogger, varargin{:}); % <-------- thechange here
fid = fopen(obj.fullfname, 'a+t');
fprintf(fid, '%s\n', sprintf(varargin{:}));
fclose(fid);
end
end
end
end
कंस्ट्रक्टर्स
एक निर्माणकर्ता एक वर्ग में एक विशेष विधि है जिसे तब कहा जाता है जब किसी वस्तु का एक उदाहरण बनाया जाता है। यह एक नियमित MATLAB फ़ंक्शन है जो इनपुट मापदंडों को स्वीकार करता है लेकिन इसे कुछ नियमों का भी पालन करना चाहिए।
MATLAB एक डिफ़ॉल्ट बनाता है क्योंकि कन्स्ट्रक्टर्स की आवश्यकता नहीं होती है। व्यवहार में, हालांकि, यह एक वस्तु की स्थिति को परिभाषित करने के लिए एक जगह है। उदाहरण के लिए, गुणों को निर्दिष्ट द्वारा प्रतिबंधित किया जा सकता है गुण । फिर, एक निर्माता डिफ़ॉल्ट या उपयोगकर्ता परिभाषित मूल्यों द्वारा ऐसी संपत्तियों को निष्क्रिय कर सकता है जो वास्तव में एक निर्माता के इनपुट मापदंडों द्वारा भेजा जा सकता है।
एक साधारण वर्ग के एक निर्माता को बुलाना
यह एक साधारण वर्ग का Person
।
classdef Person
properties
name
surname
address
end
methods
function obj = Person(name,surname,address)
obj.name = name;
obj.surname = surname;
obj.address = address;
end
end
end
एक कंस्ट्रक्टर का नाम एक वर्ग का नाम है। नतीजतन, कंस्ट्रक्टरों को इसके वर्ग के नाम से पुकारा जाता है। निम्नानुसार एक वर्ग Person
बनाया जा सकता है:
>> p = Person('John','Smith','London')
p =
Person with properties:
name: 'John'
surname: 'Smith'
address: 'London'
एक बाल वर्ग के एक निर्माता को बुला रहा है
यदि सामान्य गुण या विधियाँ साझा की जाएँ तो कक्षाएं मूल वर्गों से विरासत में प्राप्त की जा सकती हैं। जब एक वर्ग दूसरे से विरासत में मिलता है, तो संभावना है कि एक मूल वर्ग के एक निर्माता को बुलाया जाना चाहिए।
एक क्लास Member
को क्लास Person
से विरासत में मिला होता है क्योंकि Member
क्लास Person
की तरह ही प्रॉपर्टीज का इस्तेमाल करता है लेकिन इसकी payment
को भी परिभाषा में शामिल करता है।
classdef Member < Person
properties
payment
end
methods
function obj = Member(name,surname,address,payment)
obj = obj@Person(name,surname,address);
obj.payment = payment;
end
end
end
इसी प्रकार वर्ग के Person
, इसके निर्माणकर्ता को बुलाकर Member
बनाया जाता है:
>> m = Member('Adam','Woodcock','Manchester',20)
m =
Member with properties:
payment: 20
name: 'Adam'
surname: 'Woodcock'
address: 'Manchester'
Person
एक निर्माता को तीन इनपुट मापदंडों की आवश्यकता होती है। Member
को इस तथ्य का सम्मान करना चाहिए और इसलिए तीन मापदंडों वाले वर्ग Person
एक निर्माता को कॉल करना चाहिए। यह लाइन द्वारा पूरा किया गया है:
obj = obj@Person(name,surname,address);
उपरोक्त उदाहरण उस मामले को दिखाता है जब एक बच्चे की कक्षा को अपने मूल वर्ग के लिए जानकारी की आवश्यकता होती है। यही कारण है कि Member
एक निर्माता को चार मापदंडों की आवश्यकता होती है: तीन इसके मूल वर्ग के लिए और एक स्वयं के लिए।