There's a BIG difference between those two.
Let's you build upon an existing code/interface and alter it in some way. By inheriting, YOUR contract is getting all of the functions defined in the parent contract. One can even force the child contract to override certain functions by using
This is very useful and it is used in so many places. Take for example the ERC20 standard: To ensure all of the tokens have the same basic functionality like transfering, balances, supply, you need to ensure all of them inherits from the same parent contract -> This one.
So in other words, inheriting from a contract only adds more functionality to your contract.
The new keyword
On the other hand, there are instances, where you just want to deploy another contract on the blockchain. That's exactly what the
new keyword does. It literally just deploys a new contract and runs its constructor. It also returns the
address of the newly deployed contract so you can reference it just like you would do with any other contract. This deployment also costs gas, as it would if you deployed the contract yourself.
Imagine a game, that would generate a level for each user that requests it. This level could be a smart contract, generated by the main game contract. All of the users would then have an isolated contract to play with without ever interfering with any other player.