As a first substantial example, we're going to talk about kind of an ultimate extraction color. So what is color? Well, without going into all the details now, we're going to say it's a sensation in the eye from electromagnetic radiation. But from the current context what we're interested in is an ADT that allows us to write Java programs that manipulate color, and it's a fairly simple abstract data type. The values are going to be red, green, and blue values, they're going to be integer values eight bits each, which are the intensity of the red, green, and blue and the color, and you mix them on the display or on a printed page, you're going to get an associated colour. So if you have all red, no green and blue then you get this kind of red. Of all green, it's kind of a bright green, all blue it's kind of a bright blue. But if you have mixed values then all zeros is black and all 255 is white, and then in between we get the colors that we use in the slide in the book, and so, a nicer blue and a more pleasing looking magenta. So that's what a colour is, a triple of eight bit values, and if they're all the same you always get something on a grey scale and we'll see that in a minute. So the API now just has to define the set of operations that are invalid on colors. The first entry in an API for an ADT is always the constructor. So it's the name of the data type, in this case, color and it's capitalized. Then a constructor can take arguments that it can use to create an object and initialize it's values. In this case, the constructor creates an object with the given values r, g, and b. Then we have methods that a client program can call to get the various intensities back out of the data type. Then maybe other methods like make the color a bit brighter or make it a bit darker. Then usually, we have a string representation which is two string and we do that because a Java convention is if you put an object in a print line statement then it'll automatically convert it to a string or if you concatenate with it. So those are the basic methods that we're going to have for manipulating color and now we're going to write Java programs that use those methods. I forgot equals, you might want to test whether one colour is equal to another one. In this case, I have an object that's got a certain color value and has no argument, I take another color and I want to compare if my values are equal to that color's values. So, as a concrete example we're going to look at Albers squares. Josef Albers was a 20th century artist who really changed the way people think about color with a very simple device. What he did was, produced paintings with squares of different colors within one another. The relationship among these squares give a very interesting perspective about colors. He's got a book and it really changed the way people think. So, what we want to do now is write a Java program that lets us produce these squares with our colors. That's Albers in front of one of his paintings in black and white. So our goal is to write a program to generate Albers squares, and we'll do simple ones with one square in front of another. So we'll want to call the program and we want to give six command line arguments, the first three are one color, the second three are another color. So that's the kind of output that we want to get, it's two squares next to one another, one of them with the first color on the bigger square and the second color and the little square and then the other one those reversed. Then we can type in any colors we want and we can get these squares. Right away, you can see some of the interest in Albers squares in that it's not always clear to the eye that the colors are actually the same on the left and right, and anyway, they make a very interesting comparison depending on the color. So, we want to write a Java program that does this. Well, with our color ADT, that's extremely easy to do. So, we have a main program and it's going to take the r, g, b values for the first color from the command line and then create a new color. So we have a data type color, we have a variable c1, it's of type color, and to that variable we're going to assign a reference to a new object that we create by calling the color constructor with those r, g, b values, and that's how we do it. We have a well-defined data type, we have a variable that refers to an object of that data type, objects of the thing that holds the data type value, and we use the constructor to build that object. Then we do the same thing for the second color. So now we have those two colors, and now we can use the set pen color method from standard draw to get our job done. We have a little bit of geometry to do, the leftmost square centered at 0.25 and 0.5 and the right one is centered at 0.75 in half and the little squares 0.1 radius and the big square is 0.2 radius, but with that little bit of math, we set our pen color to the first color, then we draw a big square of that color and then we set it to the second color and draw the little square of that second color that draws the one on the left. Then we just switch the colors c2 first and then c1 to draw the one on the right, and that's it. That's a program that draws Albers squares and you're welcome to use this program to play around with Albers squares of any color at all that you'd like. Very simple client, but it's a profound because we're actually now computing with a different type of data we're computing with colors, not just with the numbers that Java provides us in it's primitive types. Here's another interesting computation that we'll use later on. There's a thing called the monochrome luminance of a color and it's a way to quantify how bright the colors is and that's important in plenty of applications, and we'll look at a couple of applications in a minute. There's a standard formula that has been developed for luminance, and it's a simple linear combination of the r, g, and b values, about 30 percent red, and a little less than 60 percent green and a little more than 11 percent blue. Plug in the r, g, b values and you get a number, since these add to one you get a number that's between zero and 255, that is the luminance. So that's going to be pretty easy to compute, we're going to have a static method that takes a color as argument, again, it's Sorry, it's not a built-in type of data, but we can use it the way that we use any other type of data. Then, so that static method takes C as an argument, and then it uses the defined operation get me the red component, get me the green component, get me the blue component. Then it just returns the double value that it gets by from the equation. That's a static method that computes the luminance. Then we'll have a main that reads in r, g, b from the command line, creates that color, and passes it to our luminance thing, and then It's a double value, it'll print out the integer closest to it, both of which will be between zero and 255. So, for example, 064128 the luminance is 52. Again, that's a simple program useful. We'll see that it's useful and we'll use in some applications and it's computing with this data type that is not one of Java's built-in data types. Here's just some examples of luminance. All red the luminance is 76, black at zero, white it's 255, and all other colors, those are the values. If you have a gray, then it's just going to be the same value coming out again. They're all the same, weighting them doesn't matter, it's all the same. So, those are examples of a luminance that you get for our example colors. Okay. So, we're going to look at two applications. One is, if you see on your screen a web page, there's various colors. Sometimes it's easy to read the displayed texts, other times it isn't. That has to do with this luminance. Also, converting to grayscale is another application. We'll look at both of those in just a minute. First application we'll look at is compatibility. So the question is, which font color should you use for a given background color on a display? The answer is, there's a well-known rule of thumb, that the absolute value of the differences in luminosity should be bigger than 128 if you want to be able to read them legibly. So, we can write another static method that just computes this. Takes two colors as argument, and just computes the absolute value of the difference, whether or not the absolute value of difference is bigger than 128. This is something that should always be done when putting text on a display. Just to illustrate that, here's our standard colors. A few of our standard colors. So, the red 76, black zero, white's 255, and blue 52. Now, if our font color's red, of course if it's red on red you're not going to see anything. That's black on red which has got a difference of 76, and it's legible, but not great. This is white on red, which is much more legible, and the blue on red is much less. Black, well, black on black isn't any good, but white on black is the highest difference that we can have. So, that's quite legible. The blue on black maybe not so legible. White again, in most cases, with a white background you've got a pretty good difference. So, that's just an indication and it's a good rule of thumb, and it's an example of application of computing with color. So, maybe blue, the only thing you can if you have a blue background you better use white text. So, that's concolor compatibility using luminosity. Another application is converting colors to gray scale values. It's a basic fact that I already mentioned when all three RGB values are the same, the color is going to be great. It's going to be from zero, which is black to 255 is white. There's 256 different levels. It will be one of those. So, for a given value, what's the gray that should correspond to a given color? The answer is, you just use its luminance for all three values. So, here's a static method that takes a color as argument, and produces a color as return value. The return value of color is going to be gray, and you get that just by computing the luminance of the color, given color as argument and change it to an int because it returns a double. Then make a new color, which is the gray, which you get by creating a new color with all three values set to that luminance value, and then return it. So, that's another method that we can add to our luminance library that's useful. Here's the grays corresponding to the color examples that we've tried so far. Another useful computation to be done with color. It will have applications in just a minute of that. So, the context in object-oriented programming was, how does Java represent colors? Three values between zero and 255. Are they all packed into one big int value, or they're three separate int values, or chars, or what? The answer is, we don't know. The representation is hidden. It doesn't matter to us. It's an abstract data type. System can choose to represent the color any way it wants as long as it provides the behavior that we expect through the operations that are defined for the data type. So, here's an example. Could be that what we have is the variables or the addresses of references to parts of memory that have the three values, maybe packed in bytes because they can be done in eight bits. So, maybe gray references this memory word that has an address y in it and y is the address of our free values y one after the other. We don't have to worry about how to get to the values and so forth, that's built into the data type. Maybe there's some other representation that might be used particularly when data types become more complicated. We really want to be divorced from the actual representation. That's the big benefit of using abstract data types. So, when we're using objects, we just want to remember that it's an object references is like a variable name. It's not the value, it refers to the value. So, the values in the object that the variable name refers to. So, we have just that one thing and we can pass it, return it from the method, and so forth, and when it's time to get to the values, that's all that the system needs in order to get to the values. But that detail is something that we don't have to worry about in our code. The other important use of object references is to identify an object as the one that we want to perform an operation on with the dot operator. That's actually most often what we use it for. Just to think a little bit more about abstraction, we use this famous image from the Belgian artist Rene Magritte, who put this painting. It says in French, this is not a pipe. What it actually is, is a picture of a painting of a pipe, or maybe he meant it was a painting of a pipe. But in the same way we can say in Java, these are not colors, they're references to colors. They're not actually colors, it's an abstraction. So, that's what lies at the basis of object-oriented programming. It's a natural vehicle for studying abstract models of the real world, and very, very often in programming, that's what we're doing, is working with abstract models of the real world. Just to finish with a joke. So, that's Magritte next to his brother, the surrealist plumber, that says, "That's not a pipe either," but actually it is. He's referring to an actual pipe. The joke would be a lot better if he were holding a picture of a pipe, like that is not a pipe, that's a picture of a pipe, or I can't resist inserting a computer science joke. That pipe that we talked about, that's not a pipe either. So, anyway, the whole idea of abstraction is something that's worth thinking about as we move on.