That's not true as far as I know; here is a short example to prove it...
Contract Code:
contract Base {
uint256 public x = 42;
}
contract Derived is Base {
uint256 public y = 53;
}
Truffle Test:
const Derived = artifacts.require("Derived");
contract("test", () => {
it("test", async () => {
console.log();
const derived = await Derived.new();
const slot1 = await web3.eth.getStorageAt(derived.address, 0);
const slot2 = await web3.eth.getStorageAt(derived.address, 1);
console.log(web3.utils.toBN(slot1).toString());
console.log(web3.utils.toBN(slot2).toString());
});
});
Printout:
42
53
The only reason why address _owner
and bool contact
are in the same slot is that they occupy a total of 168 bits, which fit into a single (256-bit) slot. But they do not override each other in any way, as implied in your "herein lies the problem" statement.
BTW, even from a "naive" perspective (i.e., without conducting the test above), think how catastrophic it would be for the entire inheritance paradigm, if the variables in a contract were overridden by the variables in a contract which inherited it.
The only place where storage-override requires careful handling is upon upgrading a deployed contract, typically using OpenZeppelin Contract Upgrade Scheme; and I cannot quite see how the task at hand has anything to do with that whatsoever.