Class-based programming describes precisely the common form of object-oriented programming supported by most common languages: object behavior is defined in terms of classes of which objects are instances.
Here's an example of class-oriented programming (in Python):
class Foo:
def __init__(self, x, y):
self.one = x
self.two = y
class Bar(Foo):
def __init__(self, z, **kwargs):
super().__init__(**kwargs)
self.three = z
bar = Bar(x=1, y=2, z=3)
assert bar.one == 1
assert bar.two == 2
assert bar.three == 3
bar "inherits" its support for attributes one and two from the class Foo, which Bar subclasses.
(Yes, it's exactly what you think of when you hear "object-oriented programming".)
In contrast, prototype-based programming would dispense with classes, and simply define one object in terms of another. Here's a short example taken from https://en.wikipedia.org/wiki/Prototype-based_programming, written in JavaScript. (It's also what the preceding class-based example is based on.)
var foo = {one: 1, two: 2};
var bar = Object.create(foo);
bar.three = 3;
bar.one; // 1
bar.two; // 2
bar.three; // 3
Instead of defining two classes, one of which inherits from the other and is used to define the attributes used by bar, we define a "generic" object foo that bar will inherit from. We create bar by using foo as a "prototype"; in addition to whatever we define explicitly for bar, it will also have what it inherits from foo.