I'm new to java, just about to finish programming fundamentals at uni, so I'd appreciate thorough explanation of any answers. Thanks. Also by the way I am using BlueJ as part of my university training so that might be relevant.
Anyway, here's the problem; I made a text adventure for one of my assignments, and it was very procedural designed, so I decided to revamp it afterwards into a more object oriented program. I think all you need to know about are 4 class'
(some unimportant bits are left out otherwise this would be pages long but if you think they are important let me know);
inventory
static room room;
public inventory(room room)
{
this.room = room;
}
public static room getRoom()
{
return room;
}
room
ArrayList <object> objects = new ArrayList <object>();
public ArrayList getobjects()
{
return objects;
}
object
ArrayList<String> names = new ArrayList<String>();
public ArrayList getNames()
{
return names;
}
textparse (textparse has a textparse method)
public static void textparse(String line)
{
if (line.indexOf(" ") != -1){
int space = line.indexOf(" ");
noun = line.substring(space + 1, line.length()).toLowerCase();
verb = line.substring(0, space).toLowerCase();
}
else
verb = line;
verbparse();
}
Here's the problem; room has an arraylist of objects which are present in it, object has an arraylist of names they can be called by the player. This is my code to attempt to check whether the noun recognized earlier by the textparse class matches any of the objects' names. This is in the textparse class by the way;
public static object nounparse()
{
for (int counter = 0; counter < inventory.getRoom().getobjects().size(); counter++)
{
object current = inventory.getRoom().getobjects().get(counter);
if (current.getNames().contains(noun)){
return current;
}
}
return null;
}
It returns the error 'incompatible types:java.lang.Object cannot be converted to object' referencing this line
object current = inventory.getRoom().getobjects().get(counter);
I'm not sure why it thinks that the output of this is an Object, but due to my limited experience in the field I'm not even sure what an Object is besides a general classifier of a instance of a class. Any help would be appreciated. Thanks!
You are missing a generic parameter. Your getRooms() should return ArrayList<object>, if that's your desired behavior.
Also, you should really rename your object into something else, like Thing and Item, or it may cause confusion, typo, wrong reads (i.e. you may later think you wrote Object not object), etc. All class names are also recommended to be written in Big Camel Case.
Further readings
Java Generics: Java Generics Tutorial at Oracle.com
Java naming convention: (too lazy to find one, see the answer of #DanielWiddis)
The specific source of your error is a downcast. The return type of inventory.getRoom().getobjects().get(counter) appears to be ArrayList. An ArrayList is of type Object in Java, but your lowercase object appears to be a new class definition that is not a superclass or interface for ArrayList. You could refer to it as an ArrayList or List or Collection or Object (note the capitalization), but you are trying to assign it the type object.
For more information on using superclass types, search for tutorials on Java inheritance.
If your object type really was compatible with the ArrayList you could type cast it to the object type, like:
object current = (object) inventory.getRoom().getobjects().get(counter);
However, I seriously doubt that will work in this case and is almost certainly not what you intend; don't play with typecasting unless you know what you're doing. :) I only offer this for you to do more research on typecasting to understand it better.
Also, you need to take a quick look at java coding conventions regarding capitalization of class names and use of camelCase for variable and method names; it'll make your code more readable.
Related
i am a begginer with Java but i want to ask if i can append a method inside a list and how can i make a list? here is my code
public class My_Zoo {
private String Animal_name;
private String Cohabitation;
private String Gender;
private int Weight;
private int Maximum_age;
private String Animal_code;
public void Get_Animal(String A_name, String C, String G , int W , int M_a, String A_c ){
Animal_name = A_name;
Cohabitation = C;
Gender = G;
Weight = W;
Maximum_age = M_a;
Animal_code = A_c;
}
public void Tiger(){
Animal_name = "Tiger";
Cohabitation = "mammal";
Gender = "Female";
Weight = 170;
Maximum_age = 15;
Animal_code = "A01";
}
}
As you are starting with Java I think there are some things that we might say.
Java Conventions
In Java the name of everything has a convention, you can find it here:code conventions
Let me say some that might help you:
Class names: you do not use undescore, you will allways use CamelCase with first letter in capital, for exemple insteade of My_Zoo you should use MyZoo
Variable and parameters name: same as above, but withou first letter in capital, instead of Animal_name you should use animalName
Constructors
I noticed that you tried to make 2 constructors, Get_Animal and Tiger. In java all constructors have the same name of the class. If you do not put any constructors inside a class Java will use the default constructor that looks like this.
public MyZoo(){}
The only difference allowed between constructors is it´s parameters, so you cannot create it with different names, but you can make static methods that create objects for you:
public static MyZoo Tiger(){
MyZoo tiger = new MyZoo();//create the object
//use this to set the fields you you want
return tiger; //return the desired object
}
You can make the methods getAnimal and Tiger to be this way.
More information about static methods: static methods
Lists
In Java we have a class called Collections, on java.util package. All forms of collections extends from it, including the List class.
Those classes has methods to abstracts arrays and matrices processes. More about it: Collections
As it means only to hold a set of values your question doesn´t make sense, it seems that you are asking how to put a method inside a class. To me it appears you are mistaking list with class concept.
Although with java 8 or +, you can use the functional interface an make use of the function as a high order cientizen concept and add methods to a list, that must be a list of methods from the begning, as you are starting in Java and it is a advanced concept I don´t think it is your doubt.
Methods
At least let´s go to your question, but you already made it. Methods in java has 3 basic components: access modifier, return type and a name. You made 2: Get_Animal and Tiger. In Java syntax they are methods, not constructors as I said earlier. If you want put more methods just follow these rules, it´s pretty simple: Java Methods
I hope that things got more clear for you.
And you should learn more about Object Oriented concepts as weel, for example encapisulation, so you can access your fields from outside this class, you noted them with private modifier, so outside your class no one can see them.
I'm learning about Factory Pattern and I am using THIS article as a source. In it, there is this piece of code:
class ProductFactory {
private HashMap m_RegisteredProducts = new HashMap();
public void registerProduct (String productID, Class productClass) {
m_RegisteredProducts.put(productID, productClass);
}
public Product createProduct(String productID) {
Class productClass = (Class)m_RegisteredProducts.get(productID);
Constructor productConstructor = cClass.getDeclaredConstructor(new Class[] { String.class });
return (Product)productConstructor.newInstance(new Object[] { });
}
}
I'm having a hard time figuring out how createProduct() method works. When I'm trying to use this code I get Non-static method `getDeclaredConstructor(java.lang.Class<?>...)' cannot be referenced from a static context error. productClass variable is declared but never used so there is clearly something wrong with the code but I can't figure what exactly. I checked similar questions on SO but don't know how to repurpose them for this case. Reflection is a really confusing subject for me.
My questions:
What is wrong with this code?
Why it is passing new Class[] { String.class } in getDeclaredConstrutor() method and what does it mean?
Why is it passing Object array in newInstance() instead of just single object?
Question 1
There are several things wrong about this code.
It just does not compile because cClass member is missing. Logically, It should be productClass.getDeclaredConstructor instead.
Raw HashMap is used instead of generically typed Map<String, Class<? extends Product>>. Also raw typing for Class and Constructor.
The naming m_RegisteredProducts does not respect Java naming conventions.
Question 2
new Class[] { String.class } arg aims to retrieve the constructor with a single String arg, for example public Product(String id).
It could have been retrieved with just
productClass.getDeclaredConstructor(String.class);
because it is not mandatory to create arrays for varargs.
Question 3
This array arg just looks like a blunder. The constructor instance is retrieved for one with String arg, but it is passing something else to instantiate it. So inevitably there will be an exception thrown.
Conclusion
There are too many wrong or inaccurate things in this example and probably in the article itself. I'd recommend choosing another one.
If an object reference is passed to a method, is it possible to make the object "Read Only" to the method?
Not strictly speaking. That is, a reference that can mutate an object can not be turned into a reference that can not mutate an object. Also, there is not way to express that a type is immutable or mutable, other than using conventions.
The only feature that ensure some form of immutability would be final fields - once written they can not be modified.
That said, there are ways to design classes so that unwanted mutation are prevented. Here are some techniques:
Defensive Copying. Pass a copy of the object, so that if it is mutated it doesn't break your internal invariants.
Use access modifiers and/or interface to expose only read-only methods. You can use access modifieres (public/private/protected), possibly combined with interface, so that only certain methods are visible to the other object. If the methods that are exposed are read-only by nature, you are safe.
Make your object immutable by default. Any operation on the object returns actually a copy of the object.
Also, note that the API in the SDK have sometimes methods that return an immutable version of an object, e.g. Collections.unmodifiableList. An attempt to mutate an immutable list will throw an exception. This does not enforce immutability statically (at compile-time with the static type system), but is is a cheap and effective way to enforce it dynamically (at run-time).
There has been many research proposals of Java extension to better control of aliasing, and accessibility. For instance, addition of a readonly keyword. None of them is as far as I know planned for inclusion in future version of Java. You can have a look at these pointers if you're interested:
Why We Should Not Add ''Read-Only'' to Java (yet) -- it lists and compare most of the proposals
The Checker Framework: Custom pluggable types for Java -- a non intrusive way to extend the type system, notably with immutable types.
The Checker Framework is very interesting. In the Checker Framework, look at Generic Universe Types checker, IGJ immutability checker, and Javari immutability checker. The framework works using annotations, so it is not intrusive.
No, not without decorating, compositing, cloning, etc.
There's no general mechanism for that. You'll need to write special-case code to achieve it, like writing an immutable wrapper (see Collections.unmodifiableList).
You could achieve a similar thing in most cases by cloning the Object as the first statement of the method, such as this...
public void readOnlyMethod(Object test){
test = test.clone();
// other code here
}
So if you called readOnlyMethod() and pass in any Object, a clone of the Object will be taken. The clone uses the same name as the parameter of the method, so there's no risk of accidentally changing the original Object.
No. But you could try to clone the object before passing it, so any changes made by the method won't affect the original object.
making it implement a interface which has only read only methods (no setter methods) this gives a copy of an object (road-only copy) and returning the read only instance of interface instead of returning the instance of an object itself
You could define all parameters of the objects as final but that makes the object read only to everyone.
I believe your real question is about avoiding escape references.
As pointed out in some answers to extract an Interface from class and expose only get methods. It will prevent modification by accident but it is again not a foolproof solution to avoid above problem.
Consider below example:
Customer.java:
public class Customer implements CustomerReadOnly {
private String name;
private ArrayList<String> list;
public Customer(String name) {
this.name=name;
this.list = new ArrayList<>();
this.list.add("First");
this.list.add("Second");
}
#Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public ArrayList<String> getList() {
return list;
}
public void setList(ArrayList<String> list) {
this.list = list;
}
}
CustomerReadOnly.java:
public interface CustomerReadOnly {
String getName();
ArrayList<String> getList();
}
Main.java:
public class Test {
public static void main(String[] args) {
CustomerReadOnly c1 = new Customer("John");
System.out.println("printing list of class before modification");
for(String s : c1.getList()) {
System.out.println(s);
}
ArrayList<String> list = c1.getList();
list.set(0, "Not first");
System.out.println("printing list created here");
for(String s : list) {
System.out.println(s);
}
System.out.println("printing list of class after modification");
for(String s : c1.getList()) {
System.out.println(s);
}
}
}
Ouput:
printing list of class before modification
First
Second
printing list created here
Not first
Second
printing list of class after modification
Not first
Second
So, as you can see extracting interface and exposing only get methods works only if you don't have any mutable member variable.
If you have a collection as a member variable whose reference you don't want to get escape from class, you can use Collections.unmodifiableList() as pointed out in ewernli's answer.
With this no external code can modify the underlying collection and your data is fully read only.
But again when it comes to custom objects for doing the same, I am aware of the Interface method only as well which can prevent modification by accident but not sure about the foolproof way to avoid reference escape.
Depending on where you want the rule enforced. If you are working collaboratively on a project, use final with a comment telling the next person they are not meant to modify this value. Otherwise wouldn't you simply write the method to not touch the object?
public static void main(String[] args) {
cantTouchThis("Cant touch this");
}
/**
*
* #param value - break it down
*/
public static void cantTouchThis(final String value) {
System.out.println("Value: " + value);
value = "Nah nah nah nah"; //Compile time error
}
So specifically to this method, the value will never be written to, and it is enforced at compile time making the solution extremely robust. Outside the scope of this method, the object remains unaltered without having to create any sort of wrapper.
private boolean isExecuteWriteQueue = false;
public boolean isWriting(){
final boolean b = isExecuteWriteQueue;
return b;
}
Expanding on ewernli's answer...
If you own the classes, you can use read-only interfaces so that methods using a read-only reference of the object can only get read-only copies of the children; while the main class returns the writable versions.
example
public interface ReadOnlyA {
public ReadOnlyA getA();
}
public class A implements ReadOnlyA {
#Override
public A getA() {
return this;
}
public static void main(String[] cheese) {
ReadOnlyA test= new A();
ReadOnlyA b1 = test.getA();
A b2 = test.getA(); //compile error
}
}
If you don't own the classes, you could extend the class, overriding the setters to throw an error or no-op, and use separate setters. This would effectively make the base class reference the read-only one, however this can easily lead to confusion and hard to understand bugs, so make sure it is well documented.
I have came across the following point the advantage of object composition over class inheritance. But I often see the following sentence in many articles
In object composition, functionality is acquired dynamically at run-time by objects collecting references to other
objects. The advantage of this approach is that implementations can be replaced at run-time. This is possible because
objects are accessed only through their interfaces, so one object can be replaced with another just as long as they
have the same type.
But doubt may be naive, since i am a beginner. How the implementation can be replaced in runtime? If we write a new line of code, don't we need to compile to reflect the change? Then what is meant be replacing at runtime? quite confusing.
Or any other magic, behind the scene activities happen. Can anyone please reply.
Think of an implementation of Stack. A simple implementation of Stack utilizes a List behind the scenes. So naively, you could extend ArrayList. But now if you want a separate Stack backed by a LinkedList instead, you would have to have two classes: ArrayListStack and LinkedListStack. (This approach also has the disadvantage of exposing List methods on a Stack, which violates encapsulation).
If you used composition instead, the List to back the Stack could be provided by the caller, and you could have one Stack class that could take either a LinkedList or an ArrayList, depending on the runtime characteristics desired by the user.
In short, the ability of the implementation to "change at runtime" refers not to an instance of the class being able to change its implementation at runtime, but rather that the class does not know at compile time what its precise implementation will be.
Also note that a class using composition need not allow the delegate implementation to be chosen at runtime (by the caller). Sometimes doing so would violate encapsulation, as it would give the caller more information about the internals of the class than is desirable. In these cases, composition still carries the benefits of only exposing the methods of the abstraction, and allowing the concrete implementation to be changed in a later revision.
Real-life examples
By the way, I use the example of Stack because it's not purely hypothetical. Java's Stack class in fact extended Vector, which made it forever carry the baggage of synchronization and the performance characteristics of an array-backed list. As a result, using that class is heavily discouraged.
A perfect example of correctly using composition for a collection can also be found in the Java library, in Collections.newSetFromMap(Map). Since any Map can be used to represent a Set (by using dummy values), this method returns a Set composed of the passed-in Map. The returned Set then inherits the characteristics of the Map it wraps, for example: mutability, thread safety, and runtime performance--all without having to create parallel Set implementations to ConcurrentHashMap, ImmutableMap, TreeMap, etc.
There are two strong reasons to prefer composition over inheritance:
Avoids combinatorial explosions in class hierarchy.
Can be modified at run-time
Let's say that you are writing an ordering system for a pizza parlor. You would almost certainly have a class Pizza...
public class Pizza {
public double getPrice() { return BASE_PIZZA_PRICE; }
}
And, all else being equal, the pizza parlor probably sells a lot of pepperoni pizza. You can use inheritance for this - PepperoniPizza satisfies an "is-a" relationship with pizza, so that sounds valid.
public class PepperoniPizza extends Pizza {
public double getPrice() { return super.getPrice() + PEPPERONI_PRICE; }
}
Okay, so far so good, right? But you can probably see that things we haven't considered. What if a customer wants pepperoni and mushrooms, for instance? Well, we can add a PepperoniMushroomPizza class. Already we have a problem - should PepperoniMushroomPizza extend Pizza, PepperoniPizza, or MushroomPizza?
But things get even worse. Let's say our hypothetical pizza parlor offers sizes Small, Medium, and Large. And crust varies too - they offer a thick, thin, and regular crust. If we are just using inheritance, suddenly we have classes like MediumThickCrustPepperoniPizza, LargeThinCrustMushroomPizza, SmallRegularCrustPepperoniAndMushroomPizza, et cetera...
public class LargeThinCrustMushroomPizza extends ThinCrustMushroomPizza {
// This is not good!
}
In short, using inheritance to handle diversity along multiple axes causes a combinatorial explosion in the class hierarchy.
The second problem (modification at run-time) derives from this as well. Suppose that a customer looks at the price of their LargeThinCrustMushroomPizza, gawks, and decides they'd rather get a MediumThinCrustMushroomPizza instead? Now you are stuck making a whole new object just to change that one attribute!
This is where composition comes in. We observe that a "pepperoni pizza" does indeed have an "is-a" relationship with Pizza, but it also satisfies a "has-a" relationship with Pepperoni. And it also satisfies "has-a" relationships with crust type, and size. So you re-define Pizza using composition:
public class Pizza {
private List<Topping> toppings;
private Crust crust;
private Size size;
//...omitting constructor, getters, setters for brevity...
public double getPrice() {
double price = size.getPrice();
for (Topping topping : toppings) {
price += topping.getPriceAtSize(size);
}
return price;
}
}
With this composition-based Pizza, the customer can choose a smaller size (pizza.setSize(new SmallSize())) and the price (getPrice()) will respond appropriately - that is, the run-time behavior of the method may vary according to the run-time composition of the object.
This is not to say that inheritance is bad. But where it is possible to use composition instead of inheritance to express a diversity of objects (like pizzas), composition should usually be preferred.
The other answers speak a bit about this, but I thought that an example of how the behaviour can change at runtime would be helpfull. Suppose you have a interface Printer:
interface Printer {
void print(Printable printable);
}
class TestPrinter implements Printer {
public void print(Printable printable) {
// set an internal state that can be checked later in a test
}
}
class FilePrinter implements Printer {
public void print(Printable printable) {
// Do stuff to print the printable to a file
}
}
class NetworkPrinter implements Printer {
public void print(Printable printable) {
// Connects to a networked printer and tell it to print the printable
}
}
All of the Printer classes can now be used for different purposes. TestPrinter can be used as a mock or stubb when we run tests. FilePrinter and NetworkPrinter each handle a specific case when printing. So assume we have a UI widget where the user can press a button to print something:
class PrintWidget {
// A collection of printers that keeps track of which printer the user has selected.
// It could contain a FilePrinter, NetworkPrinter and any other object implementing the
// Printer interface
private Selectable<Printer> printers;
// A reference to a printable object, could be a document or image or something
private Printable printable;
public void onPrintButtonPressed() {
Printer printer = printers.getSelectedPrinter();
printer.print(printable);
}
// other methods
}
Now at runtime when the user selects another printer and presses the a print button the onPrintButtonPressed method gets called and the selected Printer used.
That is the Polymorphism which is the core concept of OOP.
It means ‘a state of having many shapes’ or ‘the capacity to take on different forms’. When applied to object oriented programming languages like Java, it describes a language’s ability to process objects of various types and classes through a single, uniform interface.
As mark said List is a Uniform interface and its Different implementations are like ArrayList.....etc
This is interesting to answer. I am not sure whether you have used factory pattern or not. But if yo have then understanding this with that example should be good. Let me try to put it here:
Suppose you have a parent class called Pet as defined here
package com.javapapers.sample.designpattern.factorymethod;
//super class that serves as type to be instantiated for factory method pattern
public interface Pet {
public String speak();
}
And there are few subclasses such as Dog, Duck etc, sample here:
package com.javapapers.sample.designpattern.factorymethod;
//sub class 1 that might get instantiated by a factory method pattern
public class Dog implements Pet {
public String speak() {
return "Bark bark...";
}
}
package com.javapapers.sample.designpattern.factorymethod;
//sub class 2 that might get instantiated by a factory method pattern
public class Duck implements Pet {
public String speak() {
return "Quack quack...";
}
}
And there is a factory class which returns you a Pet depending on the input type, sample here:
package com.javapapers.sample.designpattern.factorymethod;
//Factory method pattern implementation that instantiates objects based on logic
public class PetFactory {
public Pet getPet(String petType) {
Pet pet = null;
// based on logic factory instantiates an object
if ("bark".equals(petType))
pet = new Dog();
else if ("quack".equals(petType))
pet = new Duck();
return pet;
}
}
Now lets see how at the run time we can have different kind of Pets created depending on the input, sample here
//using the factory method pattern
public class SampleFactoryMethod {
public static void main(String args[]) {
// creating the factory
PetFactory petFactory = new PetFactory();
System.out.println("Enter a pets language to get the desired pet");
String input = "";
try {
BufferedReader bufferRead = new BufferedReader(
new InputStreamReader(System.in));
input = bufferRead.readLine();
// factory instantiates an object
Pet pet = petFactory.getPet(input);
// you don't know which object factory created
System.out.println(pet.speak());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Now if you run the program for different kind of inputs such as "bark" or "quack", you will get a differnt pet. You can change the above program to take different inputs and create different Pets.
Here it answers your question that without changing the code, just depending on type of input you get different behavioral pets.
Hope it helps!
How the implementation can be replaced in runtime?
Let's use some code example to brighten the day (a loop that reads a new line everytime, and reprint all lines read so far):
List<String> myList = new ArrayList<String>(); // chose first "implementation"
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String line = br.readLine(); // do something like read input from the user
myCounter.resetChronometer(); // hypothetical time counter
myList.add(line); // add the line (make use my "implementation")
// and then do some final work, like printing...
for(String s: myList) {
System.out.println(s); // print it all...
}
//But, hey, I'm keeping track of the time:
myCounter.stopChronometer();
if (myCounter.isTimeTakenTooLong())
// this "implementation" is too slow! I want to replace it.
// I WILL replace it at runtime (no recompile, not even stopping)
List<String> swapList = myList; // just to keep track...
myList = new LinkedList<String>(); // REPLACED implementation! (!!!) <---
myList.addAll(swapList); // so I don't lose what I did up until now
// from now on, the loop will operate with the
// new implementation of the List<String>
// was using the ArrayList implementation. Now will use LinkedList
}
}
Just as you said: This is [only] possible because objects [myList] are accessed only through their interfaces (List<String>). (If we declared myList as ArrayList<String> myList, this would never be possible...)
I am trying to write public instance method createParther() that returns an instance of Couple. The method does its job by following these rules: one dancer in the couple must be from aList and the other bList, one dancer in the couple must be male and the other female. Neither dancer in the couple should be partnered already. If it is not possible to create a couple from amongst the unpartnered dancers, then null should be returned. If an instance of Couple is successfully created, both dancers involved in the couple should have their partnered instance variables set to true. I have attempted to list all the aList and bList to together, but then I didn't know to check the requirements as per above. Can anyone demostrate how this could be acheieved? This is not assignment.
public class FoxDancing
{
private List<Couple> coupleList;
private List<Dancer> aList;
private List<Dancer> bList;
public FoxDancing()
{
couplesList = new ArrayList<Parthers>();
aList = new ArrayList<Dancer>();
bList = new ArrayList<Dancer>();
}
public void fieldLists()
{
this.addX("Simon","AList",'m');
this.addX("Jason","AList",'m');
this.addX("Ian","AList",'m');
this.addX("Susan","BList",'f');
this.addX("Helena","BList",'f');
this.addX("Gina","BList",'f');
}
}
It looks like you'd want to have a helper method like this:
Dancer findUnpartnered(List<Dancer> list) {
for (Dancer d : list) {
if (d.isUnpartnered()) {
return d;
}
}
return null;
}
This uses a "foreach loop" for a concise, readable iteration over all Dancer in the List<Dancer>.
Then you can write something like this:
Couple createCouple() {
Dancer a = findUnpartnered(aList);
Dancer b = findUnpartnered(bList);
if (a == null || b == null) {
return null;
} else {
a.setPartnered(true);
b.setPartnered(true);
return new Couple(a, b);
}
}
While this should work, note that findUnpartnered is a O(N) linear search. If the list is of any considerable length, consider having alternative data structures, e.g. a Set<Dancer> that partitions the list into unpartnered and partnered subsets.
On generics invariance
You've written the following:
// snippet from original code
private List<Couple> coupleList;
//...
couplesList = new ArrayList<Parthers>(); // DOES NOT COMPILE!
This will not compile. A List<Partner> (assuming this is what you meant to write) is NOT a List<Couple>. Perhaps you want a new ArrayList<Couple>, or if Partner is a subtype of Couple, then perhaps you want a List<? extends Couple> coupleList.
Related questions
What is the difference between <E extends Number> and <Number>?
See also
Java Tutorials/Generics and Subtyping and More Fun With Wildcards
Angelika Langer's Java Generics FAQ - What is a bounded wildcard?
On enum
You've written the following:
// snippet from original code
this.addX("Simon","AList",'m');
this.addX("Susan","BList",'f');
// potentially "bad" use of String and char constants!
I don't know much about Foxtrot dancing, but if there's a conceptual A-list and B-list , then you may consider using an enum instead of String markers "AList" and "BList". Similarly, if there can only be male or female dancers, then enum would be much better than 'm' and 'f'.
enum FoxTrotter { A, B; }
enum Sex { MALE, FEMALE; }
See also
Java Language Guide/Enums
Related questions
Enumerations: Why? When?
Maybe I don't fully understand your requirements, but since it looks like aList is made up of males and bList females, this could be as simple as shuffling both lists and pairing couples up in a loop until one list is empty.
First write dancer class, complete with all the methods you'll need. Then consider if you want to create an instance of Couple or if you just want to have a each dancer have a reference to their partner. Once you get to this point the rest should start falling into place. :D