What is Concrete Type
Concrete type refers to the specific type that can be directly instantiated to create objects.
We can define all properties and methods. Classes and structures are examples of concrete
types.
******
"Concrete type" বলতে সেই নির্দি ষ্ট type কে বোঝায় যেটি সরাসরি অবজেক্ট তৈরি করতে ব্যবহার হতে পারে।
আমরা এর সব গুণাবলি (properties) এবং মেথড (methods) সংজ্ঞায়িত করতে পারি। ক্লাস (class) এবং
স্ট্রাকচার (structure) হল concrete টাইপের উদাহরণ।
আরও সহজভাবে বললে:
Concrete type হলো এমন একটি টাইপ (যেমন: class বা struct), যেটা দিয়ে সরাসরি অবজেক্ট তৈরি করা যায়
এবং যেটির সব বৈশিষ্ট্য ও ফাংশন ঠিকভাবে সংজ্ঞায়িত থাকে।
✅ Concrete Type with class in Swift
উদাহরণ দিয়ে বুঝি।
ধরো তু মি একটি class তৈরি করছো Car নামে:
class Car {
var brand: String
var year: Int
init(brand: String, year: Int) {
self.brand = brand
self.year = year
}
func startEngine() {
print("Engine started")
}
}
এখানে Car হলো একটি concrete class, কারণ:
● আমরা এর সব property (brand, year) এবং method (startEngine()) define করেছি।
● এবং আমরা সরাসরি এর instance বা object তৈরি করতে পারি:
let myCar = Car(brand: "Toyota", year: 2022)
myCar.startEngine() // Output: Engine started
❌ Abstract Concept (Swift-এ protocol দিয়ে করা হয়)
Swift-এ abstract class নেই, তবে protocol ব্যবহার করে abstract ধারণা বোঝানো হয়।
protocol Vehicle {
func startEngine()
}
এখানে Vehicle একটি protocol, এটা হলো abstract concept। এটিকে দিয়ে সরাসরি object তৈরি করা
❌
যাবে না:
// let v = Vehicle() এটা করা যাবে না
তবে concrete class দিয়ে এই protocol কে implement করা যায়:
class Car: Vehicle {
func startEngine() {
print("Engine started from protocol")
}
}
let myCar = Car()
myCar.startEngine() // Output: Engine started from protocol
✅ Concrete Type with struct in Swift:
struct Book {
var title: String
var author: String
func read() {
print("Reading '\(title)' by \(author)")
}
}
এখানে Book হলো একটা concrete struct type, কারণ:
● এর সব property (title, author) আর মেথড (read()) define করা হয়েছে।
● এবং সরাসরি object তৈরি করা যায়
let myBook = Book(title: "Atomic Habits", author: "James Clear")
myBook.read() // Output: Reading 'Atomic Habits' by James Clear
Swift-এ class আর struct—দুটোই concrete type হতে পারে, যদি সব property আর method define
করা থাকে। কিন্তু যদি কেবল protocol বা abstract ধারণা থাকে, তখন সেটা concrete হয় না।
******
ConcreteTypeStructure.swift
struct Person {
var name: String
var age: Int
}
let person = Person(name: "John", age: 18)
print ("Name", person. name)
print("Age", person. age)
ConcreteTypeClass.swift
class Employee {
var empName: String
var empAge: Int
var empGender: String
init(name: String , age: Int , gender: String) {
self.empName = name
self.empAge = age
self.empGender = gender
}
func empIsActive() {
print("Active")
}
}
let employee: Employee = Employee(name: "Jones", age: 33, gender: "Male")
print ("Name", employee. empName)
print("Age", employee. empName)
print("Gender", employee. empName)
employee. empIsActive()
Abstract Type
Abstract type is a type that defines a set of requirements (properties and methods) but does
not provide the actual implementation. Abstract types cannot directly instantiated
Define Abstract Type
Using protocol, the primary way to define abstract types. A protocol is an abstract type
because it declares a requirement but there is no actual implementation.
Achieve Abstract Type
To use abstract type, we need to have concrete type that conforms to the protocol and
provides concrete implementation.
AbstractType.swift
protocol Shape {
fun carea( ) - > Double
}
struct Circle : Shape {
var radius: Double
fun carea( ) - > Double {
return Double.pi*radius*radius
}
}
struct Square : Shape {
var side: Double
fun carea( ) - > Double {
return side*side
}
}
let circle = Circle (radius: 5.0)
print("Area of circle : " , circle.area( ) )
Let square = Square (side: 5.0)
print( " Area of square : ", square.area )
Conclusion
Concrete types can be directly instantiated and used. Abstract type defines but does not
provide concrete implementation. Defines common interface with multiple concrete types
enabling OOP Paradigm Polymorphism.
Access Specifiers in Swift
Modules
Module - Single unit of code distribution. Imported by using the import keyword. Build Target
- app bundle or framework called a separate module. Source File - single source file within
the same module or framework or app.
Framework and App Bundle
Bundle - A Collection of files that make up a build app. Files made up with ipa files.
Access Levels: Access Specifiers used to control the visibility and accessibility of classes,
structures, enums, properties and methods. Five different Access levels are
1. Open
2. Public
3. Internal
4. File-Private
5 . Private
Open
Most Permissive Access Level. Can be accessed from any source file from any module or
target or framework. Can be subclassed or overridden by external modules.
import UIKit
// Module
class SomeClass {
var tableView: UITableView = UITableView()
}
// From Apple documentation
// Another
open class UITableView: UIScrollView, NSCoding, UIDataSourceTranslating {
//Example
open class MyClass {
open var property: Int = 0
open func method () {}
}
//Only classes and overridable class members can be declared 'open'; use 'public'
//Replace 'open' with 'public'
open struct SomeStruct {
Public
Similar to Open Access level but with some limitations. Can be accessed from any source
file from any module or target or framework. Cannot be subclassed or overridden by external
modules.
// Public Class with UIKit
public class Some PublicClass: UIButton {
public func setButtonTitle(_ title: String) {
setTitle(title, for: .normal)
}
}
//Public Struct along with properties, functions
public struct SomePublicStruct {
public var name: String
public let color: UIColor
public init(name: String, color: UIColor) {
self.name = name
self.color = color
}
public func updateColor(to view: UIView) {
view.backgroundColor = color
}
}
Internal
Default Access level in Swift. Can be accessed from any source file from the same module
or target or framework but can not be done from external modules. Useful for defining
internal implementation details.
// Internal class and internal functions
internal class InternalViewController: UIViewController {
internal override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
private lazy var label: UILabel = {
let label = UILabel (frame: CGRect(x: 0, y: 0, width: 200, height: 200))
label.text = "Internal Label View"
label.textAlignment .center
label.font.systemFont (ofSize: 12, weight: bold)
label.numberOfLines = 1
label.textColor = .blue
label.sizeToFit()
return label
}()
private func setupUI() {
view.addSubview(label)
}
}
File-Private
Can be accessed from within the some source file. Useful for hiding implementation details
in a single source file.
Private
Most Restricted Access Level. Can be accessed from within the declaration or extensions of
the same source file. Used for Encapsulating the implementation details within a specific
scope.
// privateFile, private samefile
class Person {
fileprivate var name: String
private var nickName: String
init(name: String, nickName: String) {
self.name = name
self.nickName = nickName
}
private func privateFuncPerson() { }
fileprivate func fileprivateFuncPerson() { }
}
class SubClass: Person {
func getPerson()-> String {
privateFuncPerson() // Accessible
return nickname // Not Accessible
}
func getAnother Person()-> String {
fileprivateFuncPerson() // Accessible
return name // Accessible
}
}
extension Person {
fileprivate func modifyName() {
print("Fileprivate name is \(name)") // Accessible
print("private age is \(nickName)") // Accessible
}
}
// privateFile, private different file
//MainFile.swift
class Person {
fileprivate var name: String
private var nickName: String
init(name: String, nickName: String) {
self.name name
self.nickName
}
func introduceMe() {
print("Hello, My name is \(name)")
}
}
//PrivateFile.swift
extension Person {
fileprivate func modifyName() {
print("Fileprivate name is \(name)") // name is not accessible because of
file-private
print("private age is \(nickName)") // 'nickName' is inaccessible due to 'private'
protection level
}
}
Open vs Public
Open - Applies to class and class members not structures. Can access, subclass and
override the class or class members outside the defined module. Public applies to class,
structures and enums and their members . Can access but not subclassing or overriding
outside the defined module .
When can we use Open or Public
Use Open when we design a public API where others can extend it and modify the
implementation outside the module. Use Public when other modules can access them but
not extend or modify it.
When to use Internal
Internal plays an important role when we create a framework and will not allow other
modules / framework to access the entities. Another good example is when we work on
large-scale projects with multiple modules/frameworks.
When to use File - Private and Private
Use private when we have a data-model that contains user information. It will prevents in
modifying the data. Use file-private for utility classes or helper classes. This will help in
hiding
the implementation details and prevent from accessing or relying on them.
Don't forget about Final in Swift
Prevent the class in the framework for subclassing. Other than class, we can mark for
properties, methods. Static Dispatch can be achieved and the performance will be
increased.
We can use it to prevent overriding the methods in the framework and avoid issues.