课程讲述了测试相关的内容,包括了junit 库的使用等内容。但开始做proj1b了,一上来就是写一个接口,没接触过的我只能现学,在这里做一个记录。
1. 对于作答proj1b有所帮助的内容
- 需要将你需要的文件复制到proj1b目录下,如LinkedListDeque.java
- interface更像一个index也就是目录形式的class,对各个类进行一个统合。所以在写interface的过程中只需要把你所需要的方法(method)的“title”写出来即可,不需要写出具体的方法体
(当然,在jdk1.8以后接口内已经可以编写静态static和方法体了,default即是这其中的一种)public interface Deque <T>{ /** * 添加"default"后可以在接口中添加方法体 */ default boolean isEmpty(){ if(size()==0) return true; return false; } void addFirst(T item); void addLast(T item); int size(); void printDeque(); T removeFirst(); T removeLast(); T get(int index); } /* interface接口是父类,而class方法是子类 父类在这里只进行了申明,而具体方法的实现是在子类中写的,所以在子类中需要使用“@Override"进行声明:我在子类中所写的这些方法将覆盖父类方法中的同名函数/方法 如果不用@Override进行声明,则如果我的接口和方法出现错位或是不对应,则不会报错;添加了@Override声明之后发生这类错误会报错 */
- 类似于目录(index),interface中的各类方法,如果没有在interface文件中编写方法体,则需要在对应的class类文件中进行阐述,因此,作为目录,interface中的各类方法的形参均应与class类文件中命名一致,像我这里就是“item”而学校课程文档示例里则为“Item”
- 与上条原则相类似,如果一个class类文件关联到一个接口上(也就是“类实现接口”时),该class类文件需要将接口中所提到的所有没有方法体的方法进行实现,否则会报错
(当然也可以写成抽象类(abstract),但这里还不需要)public class LinkedListDeque <T> implements Deque<T>{}
- 关于
它可以看做是用在子类里,也就是我们的各class类文件里的的一种标识符,写不写都不影响代码运行。@Override
正如前文所述,接口文件中有的方法,在class文件里都需要有,而在写实际方法体的过程中,在接口文件中提到的每种方法体前面添加“@Override”可以让编译器帮忙检查是否与接口中的方法相对应,提高代码的可读性,减少错误发生。public interface Deque <T>{ int size(); }
public class LinkedListDeque <T> implements Deque<T>{ private int size; @Override // Function of "size()" public int size(){ return size; } }
- 关于Overload
Overload的要点在于,java允许编写同名的方法,但需要注意传入参数的种类或是数量需作出差别
2.重点代码
都是我自己码的,因为文件不少,放三个比较重要的作为参考吧。
//代码1:Palindrome.java
public class Palindrome {
/**
* "String.charAt(index)" can help us realize the target
* @param word
* @return
*/
public Deque<Character> wordToDeque(String word){
Deque<Character> output = new LinkedListDeque<>();
for(int i = 0;i<word.length();i++){
output.addLast(word.charAt(i));
}
return output;
}
/*
判别是否是回文词
*/
/**
* 方法一:直接将单词转化成Deque形式,从而使用接口取出首尾两项进行比较
* @param word
* @return
*/
// public boolean isPalindrome(String word){
// Deque<Character> d_word = wordToDeque(word);
// if(d_word.size()<=1)
// return true;
// for(int i=0;i<d_word.size()/2;i++){
// char a = d_word.removeFirst();
// char b = d_word.removeLast();
// if(a!=b)
// return false;
// }
// return true;
// }
/**
* 方法二:使用递归和帮助程序,该方法是课程中老师所推荐使用的
* @param word
* @return
*/
public boolean isPalindrome(String word){
return isPalindrome(word,0,word.length()-1);
}
private boolean isPalindrome(String word,int first,int last){
if(last<=first)
return true;
if(word.charAt(first)!=word.charAt(last))
return false;
return isPalindrome(word,first+1,last-1);
}
/**
* ---------Overload Method------------
* Overload:同样的函数名,不同的传入参数
* 这里是generalized palindrome也就是广义回文的判定
* 因为是用于offByOne的测试也就是”偏离为1的回文测试“,所以需要用到CharacterComparator
*
* Note: 这里"CharacterComparator cc"本质是使用接口进行定义,所以在我们使用过程中,
* 无论"cc"是由"OffByOne"初始化的还是由"OffByN"定义的,都符合下列方法进行运算,不需要单独分情况进行讨论
*/
public boolean isPalindrome(String word, CharacterComparator cc){
return isPalindrome(word,cc,0,word.length()-1);
}
private boolean isPalindrome(String word,CharacterComparator cc,int first,int last){
if(last<=first)
return true;
if(!cc.equalChars(word.charAt(first),word.charAt(last)))
return false;
return isPalindrome(word,cc,first+1,last-1);
}
}
//代码2:TestPalindrome.java
import org.junit.Test;
import static org.junit.Assert.*;
public class TestPalindrome {
// You must use this palindrome, and not instantiate
// new Palindromes, or the autograder might be upset.
static Palindrome palindrome = new Palindrome();
@Test
public void testWordToDeque() {
Deque d = palindrome.wordToDeque("persiflage");
String actual = "";
for (int i = 0; i < "persiflage".length(); i++) {
actual += d.removeFirst();
}
assertEquals("persiflage", actual);
} /*Uncomment this class once you've created your Palindrome class. */
/**
* Test the Origin Method (Origin Pallindrome test)
*/
@Test
public void testisPallindrome(){
String test_word_1 = "noon";
String test_word_2 = "abcddcb";
String test_word_3 = "Abccba";
String test_word_4 = "abcdcba";
boolean actual_1 = palindrome.isPalindrome(test_word_1);
boolean actual_2 = palindrome.isPalindrome(test_word_2);
boolean actual_3 = palindrome.isPalindrome(test_word_3);
boolean actual_4 = palindrome.isPalindrome(test_word_4);
assertTrue(actual_1); //actual_1为真时通过测试
assertFalse(actual_2); //actual_2为假时通过测试
assertFalse(actual_3); //actual_3为假时通过测试
assertTrue(actual_4); //actual_4为真时通过测试
}
/**
* Test the Overload Method (Generalized Pallindrome test --- off by one)
*/
@Test
public void testisPallindrome_offbyone(){
String test_word_1 = "noon";
String test_word_2 = "abcdcba";
String test_word_3 = "acedb";
String test_word_4 = "135642";
OffByOne cc = new OffByOne();
assertFalse(palindrome.isPalindrome(test_word_1,cc));
assertFalse(palindrome.isPalindrome(test_word_2,cc));
assertTrue(palindrome.isPalindrome(test_word_3,cc));
assertTrue(palindrome.isPalindrome(test_word_4,cc));
}
}
//OfferByN.java
public class OffByN implements CharacterComparator{
private int N;
public OffByN(int n){
N = n;
}
/**
* char值相邻 N 返回true,反之返回false
* @param a
* @param b
* @return
*/
@Override
public boolean equalChars(char a,char b){
if(a==b+N||a==b-N)
return true;
return false;
}
}
最后,补一张autograde的截图,算是打个卡(testofferbyone文件的一个测试没通过,应该是案例编写没考虑周全,懒得改了,就这样了)
参考: