Self signed certificates are not strictly worse than certificates signed by a reputable CA, and in all technical ways they are better than plain HTTP.
From the signing and encryption perspective they are identical. Both can sign and encrypt traffic so that it is not feasible for others to snoop or make modifications.
The difference is the way that the certificate is designated as trusted. With a CA signed certificate the user is trusting the set of trusted CAs that they have installed in their browser/OS. If they see a certificate signed by one of these they accept it and everything is fine. If it isn't (such as when self-signed) you get a big scary warning.
The reason this warning is displayed for self-signed certificates is that the browser has no idea who controls the certificate. The CAs that the browser trusts are known for verifying that they only sign the certificates of the web site owner. Therefore the browser, through extension trusts that the certificate's corresponding private key is controlled by the web site operator (and hopefully it is). With a self-signed certificate the browser has no way of knowing if the certificate was generated by the web site owner, or some man in the middle that wants to read your traffic. To be on the safe side, the browser rejects the certificate unless it is proven valid...and you get a big red warning.
The important thing about this warning is that it gives you a way to get information about the certificate. If you know what certificate you expected to get you can trust that certificate, and your browser will let you connect quite happily. This is of course great if you know the certificate you expect to get. It allows you to not even trust any CA (any trusted CA could generate a trusted certificate and intercept your traffic if they wanted to) if you want.
If you don't verify the certificate you are gaining nothing over unencrypted HTTP as anyone between you and the server could just generate their own certificate and you would be none the wiser. This could be considered worse than plain HTTP as us humans with our feeble emotions might be mislead into thinking that our connection is secure, but the only technical downside over HTTP is some wasted CPU cycles.
So for a private site, which only a couple of people access and you can distribute the certificate a self-signed is actually better than a trusted certificate. However, for the public internet you can't expect the users to verify the certificate (how would you securely transmit the details anyways) and if wise they would probably turn and run.
As for expired certificates they aren't really worse than valid ones. The reason certificates expire is so that they are invalid by the time that cracking them becomes feasible (hopefully). So the difference between a certificate that expires tomorrow and one that expired yesterday is negligible. However I would be more than a little concerned about a certificate that expired years ago.
Opportunistic Encryption
If you want to provide a little extra security there is a new standard (that is only implemented in Firefox at the moment).
Opportunistic encryption provides encryption between supporting clients and servers without authentication. It allows you to use a self-signed certificate without generating any warnings.
The reason why opportunistic encryption is better then using a self-signed certificate and HTTPS is that it provides no suggestion to the user that the connection is secure. To a user the connection appears to be a regular unencrypted HTTP connection but under the hood an SSL connection is being used to thwart passive attackers.
Again, if you are actually verifying the self-signed SSL certificate that is the best. But if you are just trying to provide unauthenticated encryption to stop traffic sniffing opportunistic encryption provides the upsides without tricking the user into thinking they are using a secure connection.