Our first example is the charge class that we wrote a client for in the previous lecture. So, we're talking about a point charge which is an idealized model of a particle that has electric charges. What we're going to do is use an abstract data type that allows us to write Java programs that manipulate point charges. So, our programs are directly manipulating objects of our new class of data. So, the values are going to be a position x, y and then electrical charge. So, the position is a pair of doubles, the electrical charge is a double value. So, here's an example of two point charges and for simplicity we keep the position in the unit square, then those are the values of the electrical charge. So that's the set of values, physician in charge and operations are, first we have a constructor that creates a new charge given x, y position and a given electrical charge value. Then one of the operations is a method called potential at that returns a double value. What it returns is, some other point x, y it gives the electrical potential at that point due to our charge. Then string representation, every class we have a string representation. We do that because in Java if you provide an object as an argument to the print statements it'll automatically call the toString and give a string representation of that object and that's very useful in debugging. Okay. So, in order to give life to this abstract data type but we want to talk a little bit about the physical world. Just a little bit, this is not a course in physics. So, potentials and measure the effect of a point charge on its surrounding. It increases as the charge value increases. So, if you have the more value, you got more potential. In a decreases in proportion to the inverse of the distance from the charge, that we're working in two dimensions. So, it's the inverse of the distance, if we're three-dimensions will be inverse of the distance squared. So mathematically, if we've got a point charge at a particular point r_x, r_y and it's got a charge q, and we've got another point x, y, we let r be the distance between our point x, y in the charge. Then, we want to come up with a formula for the potential at the point due to the charge and we use the notation capital V sub c of x, y potential at the point x, y due to the charge. There's the equation, it increases linearly with the charge and it decreases in proportion to the inverse of the distance one over r and there is a constant and that constant in the real world turns out to be 8.99 times 10 to the nine, that's a normalizing factor. So, that's what we use for the potential and another key point is that if we have a lot of charges then we can get add up the potentials due to all the charges to get the total potential at some point. When multiple charges are present, the potential at the point is the sum of the potentials due to the individual charges. So, now that's what we need to know about the real world and now we can implement our charge and we can write some clients. By the way, there's many similar laws that hold, for example the N-body problem that we've considered is an inverse square law, it's a three dimensional its gravitational force. So, this is representative of many situations. Okay. So, let's get going on the implementation. So, the best practice is to start with a test client. We talked about this in general and modular programming, but in particular for implementing an ADT. It's really good idea to understand what you expect the code to do before you write it? So, here's the test client for charge. We might want to do something like create a new charge and we give it x, y values between 0, 1, and a potential value. Maybe we want to print it out, that tests the toString method because it automatically invokes toString. Then, we also then maybe want to print out the potential at some other point due to that charge. So, that's a reasonable test client, that tests the constructor and both of the methods, and that's what you always want to try to do in a test client. So, now we take our formula and maybe do a little math by hand. So, these are judiciously chosen so that the x distance is 0.3 and the y distance is 0.4. So, the distance between those two points is 0.3 squared plus 0.4 squared equals 0.5. So, that's what r is. So, we multiply our constant 8.99 times 10 to the ninth, and then q is 20.1 and all rise to 0.5 it should give us 3.6 times 10 to the 11. So, that's what we figure out by hand. So, that went now. When we run this code, we expect it to first give a string representation of the charge which its electric potential value and then the coordinates of the point. Then, on the next line, we want to present the 3.6 times 10 to the 11. So, that's what we expect. So, that's our test client and so that's one part of the job done. So, now we have to consider the rest of the implementation. Okay, incidence variables. So, those are the data type values. So, we have a position x, y and we have a charge. We could define a data-type for points and make that our value, but for simplicity we'll just use regular doubles XY coordinates for the position rx and ry, and also for the electrical charge. That's the instance variables. Now these things have modifiers that we haven't really seen much before. So, there's private and what private does is denies clients access to these variable names and that's very important. That's what makes the data type abstract, the implementation is hidden from the client. The client can't see these variable names. If we choose some other representation of the charge were free to do it as long as the methods work as advertised in the API. So, that's what makes the data type abstract, we make the instance variables private, hidden from the client. The other one is final, and that one also is important for many different kinds of data types and we'll be talking about that more later. What it does is, it disallows any change in value after the object is constructed. So, the data type is immutable, things don't change. That's if you're representing something in the real world like a charge, it's not really going to change. So, we document that with final and also in our code we don't change the value, may well we couldn't if we document it with final. So, we'll be talking more about that later. So, the key to object oriented programming is to understand that these instance variable values are not defined just this one place, every object has instance variable value. So, there might be lots of objects. Every single one of them has the same instance variables, the same types of instance variables but they're different values, object holds datatype values. Okay. The constructor, how do we create and initialize new objects? Well, it's quite simple. We just take as argument whatever we need in order to create the object. In this case, it's just doubles with some value that the client knows. In all we do is take those values and assign them to our instance variables. Simple constructor in this case. Usually, we try to keep our constructors simple like this although many times we do more complicated things. So, the point of this is that this code refers to instance variables but there's no declaration of the type of those variables the way that we would have in a static method and that's because they're instance variables and they're declared as instance variables in the class but not within the constructor. If there's a variable reference in the constructor which hasn't been declared, that means that it's an instance variable in the class and Java knows the type from that. So what clients do is they use the new keyword to invoke the constructors. They pass arguments to it just as in a method call and this is recalling from the previous lecture where we did this and then the system creates a new object, gives it these datatype values as dictated by this code and then returns a reference to that object. The representation is hidden but just to fix ideas to get you thinking about what's underneath this, one way that a charge could be represented is depicted in this diagram. So the variable c might refer to a memory address and that memory address is where the data is kept. If there's another charge, it's going to have another variable and other data return values are referenced to a new object. Okay. So now what about the methods? So, the methods are going to be the ones that define the datatype operations that implement the APIs and that work on the datatype values. So, in this case, we need two methods potential at and toString. Potential at, where we've got our constant, we've got dx, dy and square root of dx squared plus dy squared is our r and q is our charge so it's the constant times q divided by square root of dx and dy. Now, again, notice that rx, ry and q, this code, there's no declaration of them. That's because they're instance variables and toString, we print out a string that has and gives the charge, the word at parentheses in x y. Again, that refers to q, rx and ry. The whole key to object-oriented programming is to pay attention to these instant variable references in the instance methods. Those things are values. Their types are defined as in the instance variables part of the class, and they're associated with the object that was used to invoke the method. Remember, we invoke methods in a datatype by giving an object name and then the dot operator and then the method name and we might have many objects and we can use any one of them to invoke the method. Everyone of those object has instance variable values and these references are the instance variable values in the object that was used to invoke the method. That's the key to understanding object-oriented programming. So, that's our complete implementation now. We have our instance variables, we have our constructor, we have our two methods and we have our test client and it's in a text file named charge.java and we've described everyone of these lines of code and if you type Java charge then you test out those two methods, complete implementation of an abstract datatype that represents electrical charge. Okay. So, now let's look at a more interesting client now that we have created this datatype, and let's try to visualize what the potential looks like. We're going to need a couple of static methods to get started. So, one thing is we'll have a file that includes our point charges, our positions and values and we'll just read those from standard in. So, now we can use charge just like any other type and what we want out of this method is to return an array of charges, say one per line on standard input. So, we want to return an array of charges, we just say charge array readCharges, take a list of charges and the number of charges will be the first thing in the file, so that'll be N, and then we create an array of size N of charges. Then for i from 0 to n minus 1, we'll read the xy position and the charge position, create a new charge and store that in a of i, a of i is an array of charges and that creates new charge with those values. So now we have n charges all with different values the ones given input file and then we just return that array. So, that's a static method that gets us an array of charges off values in standard input. The other thing we want to do is take the potential values at various points and convert them to a color. So, all this means is take this double value v and convert it to an 8-bit integer and we'll use a grayscale since we understand that. So, that's what this does. We take 128, 2 times 10 to the 10th and we going to say our potentials are not going to be any bigger than that. Then we'll set it to zero and set the potential, the color value that we're going to return is going to be zero. It would be 255 where it gets bigger than 255 after scale. Otherwise, we take the double value and just make it and this gives us a number just an 8-bit integer between 0 and 255. Then we'll return a grayscale of that value. So, that just takes the potential scales that are between 0 and 255 and returns a color that's the gray that has that value. So, with these two helper methods then, we have an interesting test client that's going to display, visualize the potential at all the points inside the unit square in grayscale. So, that's readCharges and toColor. Those are the ones that we talked about and so our main method, it's going to read the charges we'll make a new picture, this makes it 800 by 800 and then for every pixel, we want to assign that pixel of value and what's the value going to be? Well, we'll start out with the potential is zero. For every charge, we're going to go and re-scale to get our xy positions. So, those are xy to the unit square between 0 and 1 just by scaling by size. Then we'll just add to our running potential, the potential at that point and then we'll set the pixel and we turn it upside down because there's zeroes zeroes in the top left corner to that color. So, if we take this input file which has three charges, one at 0.5, 1.63 minus 100, one in the center with a charge of 40 and one slightly up over to the right with a charge at 20 and we run this thing, this method then will assign every pixel a grayscale value that shows us the potential and that's what we get. Pretty interesting visualization from really such a small amount of code has all to do with the idea of writing programs that work with objects of a type that we created ourself. So, now we can do more. Here's a nine charges. Some of them are positive, some of them are negative. The black ones are negative and the white ones are positive and you got a big black one close to the center and so forth. Pretty interesting display for such a small amount of code. This is data-driven now. If you want to study charges of whatever type, you can get a good visualization. Here's an example where we might be able to move the charge. This involves modification and number one the instance variables of this charge are not final anymore and number two we put code into follow the mouse but we get a pretty interesting visual display of what might happen if charges move around. Really surprising that we can get such an instructive display from a really small amount of code that we've considered so far. We run that positive one right through the middle of the negative one. So you can download this code and this data from the book site or make up your own data and have some interesting displays. Here's another very simple thing that can show the potential in an instructive way. If we change the color to once we get between a number between 0 and 255, now we'll just make it discontinuous so it's not smoothly from white to black, that line, the next to last line multiplied by 37, take the remainder, divide it by 255 still gives a number between 0 and 55 but it skips by 37. What that does to the display is give us immediately the lines of equal potential in a very graphic and instructive way. You could write programs to try to compute these curves and plot them but this is a really simple computer scientist way to do it. This is all possible because we're able to define our own datatype and write programs that manipulate it.