OOPs Part_02: ============= Access Modifiers ================ Modifier ==> can define the scope or visibility of data members or method of class. ==> Two types of modifiers: 1) Access Modifiers 2) Non-Access Modifiers ==> three levels of access modifiers: 1) Public type ==> can access in anywhere (within the package and in outside of the package) 2) Private type ==> can be restricted to class. (It can be visible within the same class) 3) Protected type ==> can be visible within the package Note: ===== In Java, access modifiers are: default private ==> Keyword protected ==> Keyword public ==> keyword In Python, no keyword is available for representing access modifiers. 1) Public type of access modifiers: =================================== class MyClass: def __init__(self): self.publicVariable = "I am Public Data Member" # public data member # public method def publicMethod(self): return "This is the Public Method Implementation" obj = MyClass() print("Public Data Member of the class = ",obj.publicVariable) print("Calling the Public Method ",obj.publicMethod()) Note: ==== Public data member can extend to outside the class also using Inheritance principle. package1: class1: a class2: inheritance print(a) package2: import package1 print(package1.a) 2) Protected type of access modifiers: ====================================== ==> data member or method of the class as protected type: we need to prefix the name with '_' ==> Protected data can be use in the class and we can extend to another class but within the same package. Package1: class1: _a class2: inheritance print(_a) Package2: import Package1 print(Package1._a) ==> Error class MyClass: def __init__(self): self._protectedVariable = "I am the protected variable" # defining the protected method def _protectedMethod(self): return "This is the Protected method implementation" obj = MyClass() print(obj._protectedVariable) print(obj._protectedMethod()) 3) Private Type of Access Modifiers: ===================================== private type ==> __ ==> can able to access within the same class we cannot extend to another class. class MyClass: def __init__(self): # private data member self.__privateVariable = "I am The Private Variable" # defining private method def __privateMethod(self): print("The Given Private Variable = ", self.__privateVariable) return "This is the private method implementation." def publicMethod(self): x = self.__privateMethod() print(x) obj = MyClass() # print(obj.__privateVariable) # print(obj.publicMethod()) obj.publicMethod() =================================================== Q-1: Can we send a public data/method from one package to another package? Ans: yes Q-2: Can we send a protected data/method from one package to another package? Ans: No Q-3: Can we access public data/method in outside the class? Ans: Yes Q-4: Can we access protected data/method in outside the class? Ans: Yes Q-5: Can we send private data from one class to another class? Ans: No we cannot access the private data in outside the class also. ===================================================================== Encapsulation with Access Modifiers =================================== is the process of wrapping/binding of data members and methods into one unit as class called as "Encapsulation". Uses: ===== 1) we can achieve the security 2) code re-usability. ==> Encapsulation can be implemented: 1) with private data members 2) with setters and getters 1) with private data members ============================ class ATM: def __init__(self,owner,balance): self.owner = owner # Public type self.__balance = balance # private type 1000 def checkBalance(self): return f"Current Balance : ${self.__balance}" def deposit(self,amount): # 10000 if amount > 0: self.__balance += amount # 11000 return f"Deposited ${amount}.{self.checkBalance()}" else: return "Invalid Deposit Amount" def withdraw(self,amount): # 2000 if 0 < amount <= self.__balance: self.__balance -= amount # 9000 return f"withdraw ${amount}.{self.checkBalance()}" elif amount > self.__balance: return "Insufficient Funds" else: return "Invalid withdraw amount!" myAccount = ATM("RaviKumar",10000) print("Hi",myAccount.owner,"Welcome to XYZ Bank") print(myAccount.checkBalance()) # print(myAccount.__balance) print(myAccount.deposit(100000)) print(myAccount.withdraw(20000)) ========================================================== Setters and Getters methods: =========================== ==> To set or get the data members of the class we can use "setters and getter methods" also. Setter Method: ============== ==> setter method can be used to set the values to the data members of the class. ==> setter method also called as "mutator methods". Syntax: def setVariable(self,name): self.variable = variable Getter Method: ============== ==> to get the value of the data members of the class, we can use "getter methods". ==> also called as "accessor methods" Syntax: def getVariable(self): return self.variable Encapsulation with setters and getters ======================================= from unittest import addModuleCleanup class BankAccount: def __init__(self,accountHolder,initialBalance): self._accountHolder = accountHolder # protected self.__initialBalance = initialBalance # private # getter method used to get the value for data member of teh class def getBalance(self): return f"Account Holder:{self._accountHolder},Balance:${self.__initialBalance:.2f}" # setter method, can set the value to the class data member (private data member) def setBalance(self,amount): if amount < 0: print("Error: Balance never be Negative.") else: self.__initialBalance = amount print(f"Balance updated to ${self.__initialBalance:.2f}") def deposit(self,amount): if amount <= 0: print("Error: Deposit amount must be positive.") else: self.__initialBalance += amount print(f"Deposited ${amount:.2f}.New Balance : ${self.__initialBalance:.2f}") def withdraw(self,amount): if amount > self.__initialBalance: print("Error: Insufficient Funds!") elif amount <= 0: print("Error: Withdraw amount must be positive.") else: self.__initialBalance -= amount print(f"Withdrawn ${amount:.2f}.Remaining Balance : ${self.__initialBalance:.2f}") account = BankAccount("RaviKumar",10000) print("Hi",account._accountHolder,"Welcome to XYZ Bank") print(account.getBalance()) account.deposit(200000) account.withdraw(10000) account.setBalance(-1000) account.setBalance(10000) account.getBalance() Types of Variables