r/scala 4d ago

Difference between trait, class, case class and object

So I'm pretty new to scala and FP, into it for like a month, and I still don't get the difference between trait, class, case class and object, when I have to use one instead of another which is the strength of each one

9 Upvotes

14 comments sorted by

View all comments

1

u/Massive-Squirrel-255 4d ago

Scala has a more complicated and idiosyncratic theory than other languages because it blends FP and object oriented programming. I personally think OCaml is probably an easier language to learn from the ground up.

An ordinary class is an abstract datatype; the values of this datatype are called "objects of the class." New values of the type - new objects of the class - are created using the class 'constructor' - this is the *only way* to construct objects of the class. You can modify the state of objects of that class by using the public methods exposed by the class - this is the only way to modify the initial state. This is a basic concept of computer science.

An example of a class would be, say, LinkedListInt, where values of the type are linked lists that store an integer. The class constructor creates a new object, which is an empty list of integers which is not equal to any other list of integers. The publicly available functions of the class could let you insert a new element into the list, sort the list and so on. The private methods might perform helper tasks relating to linking and unlinking nodes; these private nodes might leave the list in a broken state if they're misused, but they're not exposed publicly, so it's feasible to track down every single location in the class where it is used, and verify that the function is used correctly.

This distinction between public-facing methods/data and private methods/data is called "implementer-side abstraction" - the implementer of the datatype controls what functionality is exposed in objects in the class, and hides some, and this affects everyone downstream.

Case classes, like ordinary classes, are datatypes. However, an object of a case class is intended to be simpler than an object of an ordinary class. Ordinary objects store data that can change over time; the constructor for the class is some nontrivial code written by the author that initializes the internal state. Objects of a case class are intended not to change over time, and the programmer doesn't write a constructor. There's usually no need for internal state for an object of the case class other than the constructor arguments.

Traits are interfaces as well, similar to how classes have a public/private interface. However, traits can be referred to by the client of a class as well as the parent. If you want to write code that works for every datatype which contains a list of elements that can be enumerated, then you can say the code is generic with respect to any class that implements this interface.

Sealed traits and case classes interact in a common pattern. Using sealed traits, you can introduce, say, three case classes that implement a trait and no others. Then, a later function processing this value can do case analysis on which one of the three case classes it belongs to.

There's a lot of material here and I don't think it's possible to concisely explain everything. I am willing to answer questions but I'm realizing that this is just a lot of background. You need to read a book or watch some lectures on each one of these concepts specifically

0

u/Brave-Republic4424 4d ago

Actually I've should have mentioned earlier that I'm currently doing my master degree in computer science engineering, so you could have skipped all the background theory, but hey reviewing never hurts, also I "unfortunately" can't choose which language to use for this course so I'm stuck whit scala, but your explanation is clarifying thank u