previous lecture
play

Previous lecture: Array of objects Methods that handle a variable - PowerPoint PPT Presentation

Previous lecture: Array of objects Methods that handle a variable number of arguments Using a class in another T odays lecture: Why use OOP? Attributes ( private , public ) for properties and methods Inheritance:


  1. • Previous lecture: – Array of objects – Methods that handle a variable number of arguments – Using a class in another • T oday’s lecture: – Why use OOP? – Attributes ( private , public ) for properties and methods – Inheritance: extending a class • Announcement: – Project 5 due tonight – Test 2B released Tue, May 5 • Review session Sunday, 2pm EDT – Project 6, part A to be released Fri; due May 12

  2. OOP ideas • Aggregate variables/methods into an abstraction (a class) that makes their relationship to one another explicit • Object properties (data) need not be passed to instance methods — only the object handle (reference) is passed. Useful for large data sets!

  3. OOP ideas • Aggregate variables/methods into an abstraction (a class) that makes their relationship to one another explicit • Object properties (data) need not be passed to instance methods — only the object handle (reference) is passed. Useful for large data sets! • Objects (instances of a class) are self-governing (protect and manage themselves) – Hide details from clients while exposing the services they need – Don’t allow clients to invalidate data and break those services

  4. Engineering software ≠ software engineering Engineering software Software engineering • Solve a technical problem or provide • Build large, reliable systems that insight into data operate continuously • Be confident that answers are correct • Used mostly by other people – clear, documented code; testing • Make components easy to (re)use • Used mostly by yourself or your team correctly, hard to use incorrectly The design of code becomes at least as important as its output Best of both worlds: a well-engineered engineering application

  5. Restricting access to properties and methods • Hide implementation details from “outside parties” who do not need to know how things work — depend on behavior, not representation • E.g., we decide that users of Interval class cannot directly change left and right once the object has been created. Force users to use the provided methods — scale() , shift() , etc. — to cause changes in the object data • Protect data from unanticipated user action — keep properties self- consistent • Information hiding is very important in large projects – Helps avoid brittle code

  6. classdef Interval < handle % Interval experiments for k=1:5 properties fprintf('Trial %d\n', k) left a= Interval(3, 3+rand*5); right end b= Interval(6, 6+rand*3); disp(a) methods disp(b) function scale(self, f) . . . c= a.overlap(b); end if ~isempty(c) fprintf('Overlap is ') function Inter = overlap(self, other) . . . disp(c) end else . . . disp('No overlap') end end pause end end Example client code Server

  7. A server class A client class Interval left access right access Interval() … scale() … shift() … access overlap() … : Data that the client does not need to access should be protected: private Provide a set of methods for public access. The “client - server model”

  8. Preserving relationships between properties classdef Interval < handle Don’t neglect the properties default constructor left = 0; (if any); either pick a right = 0; % Invariant: right >= left sensible default state, end or make it so that methods nothing works. function Inter = Interval(lt, rt) if nargin == 2 Inter.left= lt; Inter.right= rt; end end . . . end end

  9. Constructor can be written to do error checking! classdef Interval < handle Should force users properties (clients) to use code left = 0; provided in the class right = 0; % Invariant: right >= left to create an Interval end or to change its methods property values once function Inter = Interval(lt, rt) the Interval has been if nargin == 2 created. if lt <= rt Inter.left= lt; Inter.right= rt; E.g., if users cannot else directly set the error('Error at instantiation: left>right') properties left and end end right, then they end cannot accidentally . . . “mess up” an Interval. end end

  10. Attributes for properties and methods classdef Interval < handle % An Interval has a left end and a right end • public properties (Access=private) – Client has access left right – Default end • private methods function Inter = Interval(lt, rt) – Client cannot access % Constructor: construct an Interval obj Inter.left= lt; Inter.right= rt; % Client code end r= Interval(4,6); function scale(self, f) r.scale(5); % OK % Scale the interval by a factor f w= self.right - self.left; r= Interval(4,14); % OK self.right= self.left + w*f; r.right=14; % error end disp(r.right) % error : end end

  11. classdef Interval < handle Public “ g etter” method % An Interval has a left end and a right end properties (Access=private) • Provides client the left right ability to get a property end value methods function Inter = Interval(lt, rt) Inter.left= lt; Inter.right= rt; end % Client code function lt = getLeft(self) r= Interval(4,6); % lt is the interval’s left end disp(r.left) % error lt= self.left; end disp(r.getLeft()) % OK function rt = getRight(self) % rt is the interval’s right end rt= self.right; end : end end

  12. classdef Interval < handle Public “ s etter” method % An Interval has a left end and a right end properties (Access=private) • Provides client the ability left to set a property value right end • Don’t do it unless really methods necessary! If you function Inter = Interval(lt, rt) Inter.left= lt; implement public setters, Inter.right= rt; include error checking end (not shown here). function setLeft(self, lt) % the interval’s left end gets lt self.left= lt; % Client code end function setRight(self, rt) r= Interval(4,6); % the interval’s right end gets rt r.right= 9; % error self.right= rt; end r.setRight(9) % OK : end end

  13. Prefer to use available methods, even when within same class classdef Interval < handle classdef Interval < handle properties (Access=private) properties (Access=private) left; width left; right New Interval end end implementation methods methods function Inter = Interval(lt, rt) function Inter = Interval(lt, rt) … … end end function lt = getLeft(self) function lt = getLeft(self) lt = self.left; lt = self.left; end end function rt = getRight(self) function rt = getRight(self) rt = self.getLeft() + self.getWidth(); rt = self.right; end end function w = getWidth(self) function w = getWidth(self) w= self.width ; w= self.getRight() – self.getLeft() ; end end … … end end end end

  14. Getters and setters: what have we achieved? • Getters let us change properties without changing interface • Setters (or lack thereof) let us control how properties can change – Read-only – Methods that keep them “in sync” (e.g. shift(), scale(), …) – Error checking on attempts to write • Both allow interactions to be “intercepted” – Track how many times they are changed? – Break points when debugging

  15. Quiz: access control Which of these lines are legal? classdef Square < handle shape = Square(2); A: None properties (Access=private) a1= shape.area(); s = 1 % side length 3 a2= shape.s*shape.s; end B: 1 methods (Access=public) shape.s= 1; 4 function obj = Square(side) C: 1 & 2 if nargin == 1 obj.s = side; 1 end D: 1-3 end function a = area(self) 2 a = self.s*self.s; E: All end end end

  16. OOP ideas → Great for managing large projects • Aggregate variables/methods into an abstraction (a class) that makes their relationship to one another explicit • Object properties (data) need not be passed to instance methods — only the object handle (reference) is passed. Important for large data sets! • Objects (instances of a class) are self-governing (protect and manage themselves) – Hide details from clients while exposing the services they need – Don’t allow clients to invalidate data and break those services • Maximize code reuse

  17. A fair die is… classdef Die < handle properties (Access=private) sides=6; top end What about a trick die? methods function D = Die(…) … function roll(…) … function disp (…) … function s = getSides (…) … function t = getTop (…) … end methods (Access=private) function setTop (…) … end end

  18. Separate classes — each has its own members classdef TrickDie < handle classdef Die < handle properties (Access=private) properties (Access=private) sides=6; sides=6; top favoredFace top weight=1; end end methods methods function D = Die(…) … function D = TrickDie (…) … function roll(…) … function roll(…) … function disp (…) … function disp (…) … function s = getSides (…) … function s = getSides (…) … function t = getTop (…) … function f = getFavoredFace (…) … function t = getTop (…) … function w = getWeight (…) … end end methods (Access=private) methods (Access=private) function setTop (…) function setTop (…) … end end end end

Recommend


More recommend