I follow this definition of object:An object is a value exporting a procedural interface to data or behavior. Objects use procedural abstraction for information hiding, not type abstraction. Object and and their types are often recursive. Objects provide a simple and powerful form of data abstraction. They can be understood as closures, first-class modules, records of functions, or processes. Objects can also be used for procedural abstraction. from this paperIt is taught in class that data abstraction is the methodology to create barrier between how data values are used and how data values are represented. It is taught that, an abstract data type(ADT) is some collection of selectors and constructors, together with some behaviour conditions (invariants).It is compound data that needs data processing which actually enables to think about data abstraction because the user would like to use this compound data as single unit.Building data abstraction and ADT for rational number using python objects#Usedef mulRational(x, y):    Violate abstraction by using other than constructor and selectors    return Rational(getNumer(x)*getNumer(y), getDenom(x)*getDenom(y)) #x and y are abstract datadef addRational(x, y):    Violate abstraction by using other than constructor and selectors    nx, dx = getNumer(x), getDenom(x)    ny, dy = getNumer(y), getDenom(y)    return Rational(nx * dy + ny * dx, dx * dy)def eqRational(x, y):    Violate abstraction by using other than constructor and selectors    return getNumer(x) * getDenom(y) == getNumer(y) * getDenom(x)def toString(x):    Violate abstraction by using other than constructor and selectors    return '{0}/{1}'.format(getNumer(x), getDenom(x))#Representation# Representation is provided by constructors and selectors using tuples#Constructorfrom fractions import gcddef Rational(n, d):    Construct a rational number x that represents n/d.    g = gcd(n, d)    return (n // g, d // g) #this is concrete representation of a rational number#Selectorfrom operator import getitemdef getNumer(x):    Return the numerator of rational number x.    return getitem(x, 0)#Selectordef getDenom(x):    Return the denominator of rational number x.    return getitem(x, 1)Rational number has compound data (n,d) that enables to build data abstraction, Because user would like to use this compound data as single unit.Below implementation is done with different representation.#Usedef mulRational(x, y):    Violate abstraction by using other than constructor and selectors    return pair(getitem_pair(x,0) * getitem_pair(y,0), getitem_pair(x,1) * getitem_pair(y,1))def addRational(x, y):    Violate abstraction by using other than constructor and selectors    nx, dx = getitem_pair(x,0), getitem_pair(x,1)    ny, dy = getitem_pair(y,0), getitem_pair(y,1)    return pair(nx * dy + ny * dx, dx * dy)def eqRational(x, y):    Violate abstraction by using other than constructor and selectors    return getitem_pair(x,0) * getitem_pair(y,1) == getitem_pair(y,0) * getitem_pair(x,1)def toString(x):    Violate abstraction by using other than constructor and selectors    return '{0}/{1}'.format(getitem_pair(x,0), getitem_pair(x,1))#Representation#Representation is provided by constructors and selectors using higher order functions#Constructor def pair(x, y):    from fractions import gcd    g = gcd(x, y)    Return a functional pair    def dispatch(m):          if m == 0:            return x // g        elif m == 1:            return y // g    return dispatch#Selectordef getitem_pair(p, i):    Return the element at index of pair p    return p(i)In the above code, Constructors & selectors constitute ADT.In the above two implementations:There is an abstract data type that supports an invariant:a) If we construct rational number x from numerator n and denominator d, then  getNumer(x)/getDenom(x) must equal n/d.b) If we construct rational number x from numerator n and denominator d then getitem_pair(p, 0)/getitem_pair(p, 1) must equal n/dIn the above 2 implementations we have 3 abstraction barriers:Parts of the program that work with rational numbers to perform computation use mulRational(..), addRational(..), eqRational(..) && toString(..) computation processes only.Parts of the program that implement mulRational(..) use constructor and selectors only.Parts of the program that implement constructors & selectors would use built in datatypes or built-in functions.My question:Is my understanding correct on designing data abstraction and ADT for rational numbers? I disagree with below three points.1)This paper says: While objects and ADTs are fundamentally different, they are both forms of data abstraction.2)This paper: An abstract data type is a structure that implements a new type by hiding the  representation of the type and supplying operations to manipulate its values.3)This paper says:  Abstract data types depend upon a static type system to enforce type abstraction.Reason, In the above code,Firstly,  Data abstraction has it's own identity by enforcing a barrier between representation and use. Each above implementation has set of objects that build Data abstraction and  supply operations[mulRational]Secondly, ADT is just the collection of constructor and selectors which support some invariants to validate the representation. ADT in the above code did not implement a new type. ADT did not supply operations. ADT does not require type system.
Building Data abstraction for rational numbers using objects
object oriented;abstraction;python 3.x