Это решение ES6 работало для меня:
multiple-inheritance.js
export function allOf(BaseClass, ...Mixins) {
function copyProperties(target, source) {
const allPropertyNames = Object.getOwnPropertyNames(source).concat(Object.getOwnPropertySymbols(source))
allPropertyNames.forEach((propertyName) => {
if (propertyName.match(/^(?:constructor|prototype|arguments|caller|name|bind|call|apply|toString|length)$/))
return
Object.defineProperty(target, propertyName, Object.getOwnPropertyDescriptor(source, propertyName))
})
}
class Base extends BaseClass
{
constructor (...args) {
super(...args)
Mixins.forEach((Mixin) => {
copyProperties(this, new Mixin(...args))
})
}
}
Mixins.forEach((mixin) => {
copyProperties(Base.prototype, Mixin.prototype)
})
return Base
}
main.js
import { allOf } from "./multiple-inheritance.js"
class A
{
constructor(name) {
this.name = name
}
sayA() {
return this.name
}
}
class B
{
constructor(name) {
this.name = name
}
sayB() {
return this.name
}
}
class AB extends allOf(A, B)
{
sayAB() {
return this.name
}
}
const ab = new AB("ab")
console.log("ab.sayA() = "+ab.sayA()+", ab.sayB() = "+ab.sayB()+", ab.sayAB() = "+ab.sayAB())
Урожайность на консоли браузера :
ab.sayA() = ab, ab.sayB() = ab, ab.sayAB() = ab
Можно зеркально отразить значение как так:
myVal = !myVal;
, таким образом, Ваш код сократился бы вниз к:
switch(wParam) {
case VK_F11:
flipVal = !flipVal;
break;
case VK_F12:
otherVal = !otherVal;
break;
default:
break;
}
Если Вы знаете, что значения 0 или 1, Вы могли бы сделать flipval ^= 1
.
Очевидно Вам нужен шаблон "фабрика"!
KeyFactory keyFactory = new KeyFactory();
KeyObj keyObj = keyFactory.getKeyObj(wParam);
keyObj.doStuff();
class VK_F11 extends KeyObj {
boolean val;
public void doStuff() {
val = !val;
}
}
class VK_F12 extends KeyObj {
boolean val;
public void doStuff() {
val = !val;
}
}
class KeyFactory {
public KeyObj getKeyObj(int param) {
switch(param) {
case VK_F11:
return new VK_F11();
case VK_F12:
return new VK_F12();
}
throw new KeyNotFoundException("Key " + param + " was not found!");
}
}
: D
</sarcasm>
Только для получения информации - если вместо целого числа Ваше обязательное поле является единственным битом в большем типе, используйте 'xor' оператор вместо этого:
int flags;
int flag_a = 0x01;
int flag_b = 0x02;
int flag_c = 0x04;
/* I want to flip 'flag_b' without touching 'flag_a' or 'flag_c' */
flags ^= flag_b;
/* I want to set 'flag_b' */
flags |= flag_b;
/* I want to clear (or 'reset') 'flag_b' */
flags &= ~flag_b;
/* I want to test 'flag_b' */
bool b_is_set = (flags & flag_b) != 0;
Это, кажется, дискуссия... Heh. Вот другой varation, который я предполагаю, находится больше в категории, "умной", чем что-то, что я рекомендовал бы для производственного кода:
flipVal ^= (wParam == VK_F11);
otherVal ^= (wParam == VK_F12);
я предполагаю, что это - преимущества:
И так же, как очевидный недостаток
, Это близко к использованию решения @korona?: но взятый один (маленький) шаг вперед.
codegolf'ish решение было бы больше похоже:
flipVal = (wParam == VK_F11) ? !flipVal : flipVal;
otherVal = (wParam == VK_F12) ? !otherVal : otherVal;
Я предпочитаю решение T John, но если Вы хотите пойти весь код-golfy, Ваш оператор логически уменьшает до этого:
//if key is down, toggle the boolean, else leave it alone.
flipVal = ((wParam==VK_F11) && !flipVal) || (!(wParam==VK_F11) && flipVal);
if(wParam==VK_F11) Break;
//if key is down, toggle the boolean, else leave it alone.
otherVal = ((wParam==VK_F12) && !otherVal) || (!(wParam==VK_F12) && otherVal);
if(wParam==VK_F12) Break;
Очевидно Вам нужно гибкое решение, которое может поддерживать типы, подменяющие булевской переменной. Следующее допускает это:
template<typename T> bool Flip(const T& t);
можно тогда специализировать это для различных типов, которые могли бы симулировать быть булевской переменной. Например:
template<> bool Flip<bool>(const bool& b) { return !b; }
template<> bool Flip<int>(const int& i) { return !(i == 0); }
пример использования этой конструкции:
if(Flip(false)) { printf("flipped false\n"); }
if(!Flip(true)) { printf("flipped true\n"); }
if(Flip(0)) { printf("flipped 0\n"); }
if(!Flip(1)) { printf("flipped 1\n"); }
нет, я не серьезен.