Overriding members provided by traits is possible, but in my experience isn’t common. Usually you just add a trait to the class, and presto, the class has a bunch of additional functionality. If you’re overriding what a trait is doing, an interface is probably the better choice.
I’m just not sure how that relates to this conversation.
This is the “right” way to use a trait:
<?php
trait VoidScreamer {
public function screamIntoTheVoid(): void {
echo 'AAAAAAAAAAA';
}
}
class Person {
use VoidScreamer;
}
$person = new Person();
$person->screamIntoTheVoid();
?>
Person is its own class. For the sake of argument, assume it wouldn’t make sense to make Person a subclass of VoidScreamer. If I wanted a completely independent class to have the same functionality, I just create the class and use the trait. Alternatively, I could use a singleton static method, interface, and then just fill in the method to do the same thing on each class. But why would I want to do that when this is simpler and more organized?
So… what does object-oriented calls vs procedural calls have to do with our conversation about traits?
currently xojo can’t handle it, it looks simpler in php with 3 rows of source code.
this php example missing a function input and output to match a real use case and the class some properties.
if your methods have more than a few arguments you will gave that method an object(class) which means it is not neutral and you need an interface.
this call is mindless, it not interact with the person class.
Yeah, there are always workarounds. But sometimes, it’s the best solution. I could keep expanding the example a bit, but the fact of the matter is real-world examples are hard to come by. Yet, I gave one in my original post. That’s usually where traits come in: when you need something like multiple inheritance in a language that does not support multiple inheritance. So what you should be looking for is examples of multiple inheritance, and figure out a way to do that in Xojo. Then it’s more obvious how traits can be helpful. In my case, I have classes that are logically two different things.
Of course, I am working on a solution but that doesn’t mean that traits don’t have a benefit.
But anyway, if you want a trait example that actually uses the Person class, here:
<?php
trait Screamer {
public function screamMyName(): void {
echo strtoupper($this->firstName);
}
}
class Person {
use VoidScreamer;
protected string $firstName;
public function __construct($firstName) {
$this->firstName = $firstName;
}
}
$person = new Person('Ted');
$person->screamMyName();
?>
at least you need the context menu goto definition.
in xojo you can not add other things into same file or menu entry, everything is separated,
so i guess if trait would be integrated it is not at the same place, it would be similar like add module.
Yes, that is correct. As I opened with, traits work as if you had copied and pasted the members into the implementing class. So yes, it would be a compile error not to have a firstName property.
This does seem like a handy thing. So if I added the Screamer Trait to a “car” which is generally very different than a person, because it has doors and engine and such – I could set $car = new Car(‘Mater’); and then $car ->screamMyName(); Otherwise you would have to create some sort of parent class called “sentient thing” that both a person and a car would have to be a subclass of.
It may be add this, this and that behaviors (with enums, consts and methods) to this “structured data-container” (class or struct, if class, it may contain properties)
The compiler (or linter) may say “there’s this and that conflict” between those members of those traits (and show them). Then you can use the composition powers of the language to resolve them, as “Traits A and B have screamMyName conflict” and you say “always use Trait A->screamMyName, never B->screamMyName” or “let B->screamMyName be know as screamMyNameB” in this composition (so the conflict also disappear and you can use both methods). And you never need to touch what you designed for the original Traits, just teach new Traits to new data-containers or create a new compound Trait you can apply everywhere too.