Patterns

No inheritance: traits & composition

Rust has no contract inheritance. Shared behavior comes from traits (with default methods) and shared state from composition.

Solidity leans on inheritance — contract Token is Ownable, Pausable. Rust has no implementation inheritance at all. You reuse code two other ways: traits for shared behavior (they can carry default methods) and composition for shared state (embed a struct).

Reusing an "Ownable" behavior
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

abstract contract Ownable {
    address public owner;
    modifier onlyOwner() {
        require(msg.sender == owner, "not owner");
        _;
    }
}

// inherit owner + onlyOwner
contract Token is Ownable {
    uint256 public supply;
}
Rust
use near_sdk::{near, env, require, AccountId};

// shared BEHAVIOR as a trait with a default method
trait Ownable {
    fn owner(&self) -> &AccountId;

    fn assert_owner(&self) {
        require!(env::predecessor_account_id() == *self.owner(), "not owner");
    }
}

// shared STATE by composition — embed the owner field
#[near(contract_state)]
pub struct Token {
    owner: AccountId,
    supply: u128,
}

// implement the one required method; get assert_owner for free
impl Ownable for Token {
    fn owner(&self) -> &AccountId {
        &self.owner
    }
}
Coming from EVM

contract Token is Ownable ↔ impl Ownable for Token. A trait with default methods (assert_owner) is the closest thing to inheriting a base function or modifier — you implement the small required piece and get the rest.

Shared *state* is composition, not inheritance: you embed the fields (or a whole sub-struct) you need. There is no diamond problem and no super — just fields and trait methods.

For the token standards, near-contract-standards gives you structs to embed plus macros that generate the trait impls — that is how you "inherit" NEP-141/171 behavior in practice.