Table of Contents
Let’s look at an example
How can we solve this problem?
Implement interface in C language
A real use case
Conclusion
Home Java javaTutorial Object Orientation in C? Implementing an interface from scratch.

Object Orientation in C? Implementing an interface from scratch.

Jan 21, 2025 am 10:05 AM

Orientação a Objetos em C? Implementando uma interface do zero.

I have always been curious about computers and always thought: "Okay, I know how to use it, but how does it really work?" In this process, I often do a thought experiment: If I were asked to start from Starting from scratch, what would I do? In this article, we will explore how interfaces work in object-oriented programming (using Java), and then implement a humble version of the interface in C.

Let’s look at an example

Our example is simple: calculate the price of a vehicle. If it's a car, the price will be based on its top speed; if it's a motorcycle, the price will be based on its displacement. We first define the behavior of the vehicle using an interface:

public class Main {
    public interface Vehicle {
        Integer price();
    }
}
Copy after login
Copy after login

Nothing special here, just a method that returns an integer. Now let's implement the car class:

public class Main {
    // ...

    public static class Car implements Vehicle {
        private final Integer speed;

        public Car(Integer speed) {
            this.speed = speed;
        }

        @Override
        public Integer price() {
            return speed * 60;
        }
    }
}
Copy after login
Copy after login

Very classic: an implementation of a constructor and price method, multiplying the speed by 60. Now, let's implement the motorcycle class:

public class Main {
    // ...

    public static class Motorcycle implements Vehicle {
        private final Integer cc;

        public Motorcycle(Integer cc) {
            this.cc = cc;
        }

        @Override
        public Integer price() {
            return cc * 10;
        }
    }
}
Copy after login
Copy after login

Almost the same, the only difference is that now we multiply the displacement by 10. Then, we implement a method to print the vehicle price:

public class Main {
    // ...

    public static void printVehiclePrice(Vehicle vehicle) {
        System.out.println("$" + vehicle.price() + ".00");
    }
}
Copy after login
Copy after login

No secrets. Finally, our main method:

public class Main {
    // ...

    public static void main(String[] args) {
        Car car = new Car(120);
        Motorcycle motorcycle = new Motorcycle(1000);

        printVehiclePrice(car);
        printVehiclePrice(motorcycle);
    }
}
Copy after login
Copy after login
<code>$ java Main.java
00.00
000.00</code>
Copy after login
Copy after login

This is the model we want to achieve, but now implemented from scratch in C.

How can we solve this problem?

When I think of objects, the first thing that comes to mind is a set of data that represents a state and methods to operate and manage that state. The most direct way to represent a data collection in C language is a structure. For methods, the closest approach is a function that receives a state as a parameter. This state will correspond to this in the class, for example:

typedef struct {
    int height_in_cm;
    int weight_in_kg;
} Person;

float person_bmi(Person *person) {
    float height_in_meters = (float)person->height_in_cm / 100;
    float bmi =
        (float)person->weight_in_kg / (height_in_meters * height_in_meters);

    return bmi;
}
Copy after login
Copy after login

Here, we define a person's data in the Person structure and use these data to perform simple calculations. This is the closest structure to a class we can have in C. Maybe using function pointers in structs is also a good idea? Well, I’ll leave that for the next article.

Okay, we have a class-like structure. Now, how do we define interface in C language? If you think about it, the compiler/interpreter doesn't do magic to guess which classes implement the interface. It determines this at compile time and replaces all the parts where we use the interface with concrete types. In the compiled program, the interface doesn't even exist.

Since the C language compiler does not provide this possibility, we must implement this solution ourselves. We need to know all the types that implement our interface and figure out how to use the functions of these implementations.

Implement interface in C language

First, let’s define the skeleton of our humble interface. We will create an enumeration that contains the different implementations and signatures of our functions.

public class Main {
    public interface Vehicle {
        Integer price();
    }
}
Copy after login
Copy after login

Here we define our enum which contains the implementation we will implement later. This may not seem like it, but this part is very important. Next, we declare the vehicle_free function (will be explained later) and the vehicle_price function, which we want to implement in our "class". Now let’s look at the car implementation:

public class Main {
    // ...

    public static class Car implements Vehicle {
        private final Integer speed;

        public Car(Integer speed) {
            this.speed = speed;
        }

        @Override
        public Integer price() {
            return speed * 60;
        }
    }
}
Copy after login
Copy after login

The car_init function initializes a new "object" Car in memory. In Java this will be done automatically via new. Here we need to do it manually. The vehicle_free function will be used to release the memory allocated by any previously initialized "object", implemented using car_free etc. The implementation for motorcycles is very similar:

public class Main {
    // ...

    public static class Motorcycle implements Vehicle {
        private final Integer cc;

        public Motorcycle(Integer cc) {
            this.cc = cc;
        }

        @Override
        public Integer price() {
            return cc * 10;
        }
    }
}
Copy after login
Copy after login

Almost the same, except now we initialize with VEHICLE_MOTORCYCLE and multiply by 10. Now let’s look at the function that prints the vehicle price:

public class Main {
    // ...

    public static void printVehiclePrice(Vehicle vehicle) {
        System.out.println("$" + vehicle.price() + ".00");
    }
}
Copy after login
Copy after login

So simple...it doesn't look like we're doing much work. Now, the last and most important point is that we have to implement the functions we declared in the interface definition above, remember? Fortunately, we don't even need to think about this implementation. We always have a simple exhaustive switch/case and that's it.

public class Main {
    // ...

    public static void main(String[] args) {
        Car car = new Car(120);
        Motorcycle motorcycle = new Motorcycle(1000);

        printVehiclePrice(car);
        printVehiclePrice(motorcycle);
    }
}
Copy after login
Copy after login

Now we can use everything we did:

<code>$ java Main.java
00.00
000.00</code>
Copy after login
Copy after login
typedef struct {
    int height_in_cm;
    int weight_in_kg;
} Person;

float person_bmi(Person *person) {
    float height_in_meters = (float)person->height_in_cm / 100;
    float bmi =
        (float)person->weight_in_kg / (height_in_meters * height_in_meters);

    return bmi;
}
Copy after login
Copy after login

Success! But you might be thinking: "Well, what's the use?"

A real use case

One of my favorite types of projects is parsers, from parsers to simple math expression parsers. Typically when you implement these parsers you encounter something called an AST (Abstract Syntax Tree). As the name suggests it is a tree which will represent the syntax you are dealing with, for example the variable declaration int foo = 10; is a node of the AST which contains three other nodes, a type node, for int, an identifier node, for foo, and an expression node, for 10, which contains another integer node with a value of 10. See how complicated it is?

When we do this in C, we have to choose between a huge struct with multiple fields to represent any possible AST node, or an abstract definition using multiple small structs, each Structures represent different nodes, just like we do here with our "interfaces". If you want to see a simple example, in this math expression parser I implemented the second approach.

Conclusion

Nothing a compiler or interpreter does is magic. It's always a fun exercise to try to implement something yourself. Hope this was a helpful read. Thanks!

The above is the detailed content of Object Orientation in C? Implementing an interface from scratch.. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How does Java's classloading mechanism work, including different classloaders and their delegation models? How does Java's classloading mechanism work, including different classloaders and their delegation models? Mar 17, 2025 pm 05:35 PM

Java's classloading involves loading, linking, and initializing classes using a hierarchical system with Bootstrap, Extension, and Application classloaders. The parent delegation model ensures core classes are loaded first, affecting custom class loa

How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache? How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache? Mar 17, 2025 pm 05:44 PM

The article discusses implementing multi-level caching in Java using Caffeine and Guava Cache to enhance application performance. It covers setup, integration, and performance benefits, along with configuration and eviction policy management best pra

How can I implement functional programming techniques in Java? How can I implement functional programming techniques in Java? Mar 11, 2025 pm 05:51 PM

This article explores integrating functional programming into Java using lambda expressions, Streams API, method references, and Optional. It highlights benefits like improved code readability and maintainability through conciseness and immutability

How can I use JPA (Java Persistence API) for object-relational mapping with advanced features like caching and lazy loading? How can I use JPA (Java Persistence API) for object-relational mapping with advanced features like caching and lazy loading? Mar 17, 2025 pm 05:43 PM

The article discusses using JPA for object-relational mapping with advanced features like caching and lazy loading. It covers setup, entity mapping, and best practices for optimizing performance while highlighting potential pitfalls.[159 characters]

How do I use Maven or Gradle for advanced Java project management, build automation, and dependency resolution? How do I use Maven or Gradle for advanced Java project management, build automation, and dependency resolution? Mar 17, 2025 pm 05:46 PM

The article discusses using Maven and Gradle for Java project management, build automation, and dependency resolution, comparing their approaches and optimization strategies.

How do I use Java's NIO (New Input/Output) API for non-blocking I/O? How do I use Java's NIO (New Input/Output) API for non-blocking I/O? Mar 11, 2025 pm 05:51 PM

This article explains Java's NIO API for non-blocking I/O, using Selectors and Channels to handle multiple connections efficiently with a single thread. It details the process, benefits (scalability, performance), and potential pitfalls (complexity,

How do I create and use custom Java libraries (JAR files) with proper versioning and dependency management? How do I create and use custom Java libraries (JAR files) with proper versioning and dependency management? Mar 17, 2025 pm 05:45 PM

The article discusses creating and using custom Java libraries (JAR files) with proper versioning and dependency management, using tools like Maven and Gradle.

How do I use Java's sockets API for network communication? How do I use Java's sockets API for network communication? Mar 11, 2025 pm 05:53 PM

This article details Java's socket API for network communication, covering client-server setup, data handling, and crucial considerations like resource management, error handling, and security. It also explores performance optimization techniques, i

See all articles