Connascence (con-nass’-sense) is a term that combines ideas from coupling and the single responsibility principle Connascence means that (1) if you change A, you have to change (or at least check) B to keep the program working correctly, or (2) some change outside of A and B would require both A and B to be changed to keep the program working correctly.
There are many types of connascence, here are a few listed in Chapter 8 of What Every Programmer Should Know About Object-Oriented Design:

Connascence of name. This one’s easy: variables have names, so if you change the declaration, you have to change all referring code. These days, that’s usually easy to do with refactoring tools like ReSharper, but consider a SqlDataReader. If you change a column from “foo” to “bar”, then you have to change your SqlDataReader references from dr["foo"] to dr["bar"], and then if you are mapping to an object, you might even want to change MyObject::Foo to MyObject::Bar.
Connascence of type/class. If a variable has a type, (like int), and you decide to change it to string, you (may) need to change code that sets it to an int. C#, a static language, will give you build errors (hopefully) when you come across this situation, but consider a language like PHP or Ruby where, depending on the situation, might work just fine or might not work how you intend in this situation.
Connascence of meaning. This one is a real pain. Let’s say that account number 0 is defined to always be the administrator. If you do that, then your code might have a bunch of if(accountNum == 0) { doAdminStuff(); } all over the place. If you ever changed that, you’d have to make changes almost everywhere.
Connascence of algorithm. This is very similar to connascence of meaning: if you know that the elements in some sort of generic collection (say, List<T>) always iterate the same order that they were inserted, you could build some piece of code to take advantage of that. However, if List<T> doesn’t make any claims to being sorted or deterministic, a change down the road could break all of your code until you change it to a SortedList<K,V>.
Connascence of position. Code must be in the right sequence or the right adjacency in order to work. The only example I could think of for this is method arguments: unless they are named arguments, if you want to switch them, you have to switch them everywhere the method is used. Of course, if they are named arguments, then maybe you are just trading one connascence for another (which might be more easily refactored).
According to Page-Jones, those are all types of “static” connascence, which applies to the code itself. “Dynamic” connascence applies to the execution, or the runtime of the code.
Connascence of execution. This is similar to connascence of position. In some languages, a variable must be initialized before it is used, and that’s an example.
Connascence of timing. This one is related to real-time systems, with which I don’t have much experience. Page-Jones gives an example of an X-ray machine that must turn off n milliseconds right after it is turned on.

Connascence of value. The values of an object or variable are constrained. For instance, if you define a rectangle by 4 points, then those 4 points just can’t be any point. Page-Jones also gives the all-to-familiar example of (bidirectional) database synchronization, where two databases are required to hold redundant information. Any minor change in either database could make the whole bridge go kablooey.
Connascence of identity. If an object A and object B must both point to the same object C in order to work correctly, or in concert, then A and B have connascence of identity. So, if A is pointing to some database, for instance, B must be pointing to the same database. If they aren’t they might still work, but show the wrong data to the user, or they might just biff completely at runtime.
Contranascence. So, this is not the opposite of connascence, but rather a “connascence of difference”. If you have an int i; and an int j;, you can’t rename j to i without also renaming i to j (or something else). These variables are related by the fact that they are different. Multiple inheritance can cause all sorts of problems here, as can a language without namespaces.
So, what does all this mean? Page-Jones posits that connascence and contranascence are absolutely key to understanding modern software development. Without encapsulation, managing connascence and contranascence become incredibly hard. A huge chunk of procedural code would be very difficult to make changes to, as it could incur one or more of the above listed connascences and break the program. So, there are three guidelines that he lists to reduce that problem in an object-oriented system:
- Minimize overall connascence by breaking the system into encapsulated components (duh).
- Minimize any remaining connascence that crosses encapsulation boundaries (single responsibility principle).
- Maximize connascence within encapsulation boundaries. (I think this is the key)
Basically, keep like things together and keep unlike things apart. And using the types of connascence, “likeness” can now be qualified.