201871010116-祁英红《面向对象程序设计(java)》第八周学习总结
项目 |
内容 |
《面向对象程序设计(java)》 |
https://home.cnblogs.com/u/nwnu-daizh/ |
这个作业的要求在哪里 |
https://www.cnblogs.com/nwnu-daizh/p/11703678.html |
作业学习目标 |
|
随笔博文正文内容包括:
第一部分:总结第六章理论知识(30分)
一、接口:
(1)接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义。如果类遵从某个特定接口,那么就履行这项服务。
(2)Java不支持多继承性,即一个子类只能有一个父类;单继承使得java简单,易于管理,但如果要克服单继承性的缺点就要使用接口技术,是一个类可以实现多个接口,用关键字interface关键字来定义一个接口。
(3)接口声明:interface 接口名; 接口体:包括常量定义和方法定义,方法只允许声明不允许实现。
(4)接口使用:class A implements print,add 或者 class A extends A1 implements print,add
(5)接口中的所有方法自动地属于public,因此,在接口中声明方法时,不必提供关键字public。
(6)接口不能含有实例域,提供实例域和方法实现的任务应该由实现接口地那个类来完成,为了让类实现一个接口:1)将类声明为实现给定的接口。2)对接口中的所有方法进行定义。
(8)当某个类使用接口的时候,必须给出所有方法的实现,方法的类型、参数一定要和接口的一致;接口的方法默认为public abstract,故类在实现时一定不能漏写public关键字;接口常量默认关键字为public static。
(9)int compareTo(T other)
用这个对象与other进行比较,如果这个对象小于other则返回负值,如果相等则返回0,否则返回正值。
static void sort(Object[ ] a)
使用mergesort算法对数组a中的元素进行排序。要求数组中的元素必须属于实现了Comparable接口的类,并且元素之间必须是可比较的。
static int compare(int x,int y)7
如果x<y返回一个一个负整数,如果x和y相等,则返回0,否则返回一个负整数。
static int compare(double x,double y)1.4
如果x<y返回一个负数,如果x和y相等则返回一个0,否则返回一个负数。
(10)接口不是类,不能使用new运算符实例化一个接口,x=new Comparable(...); //ERROR
不能构造接口的对象,但能声明接口的变量,接口变量必须引用实现了接口的类对象,可以使用instance检查一个对象是否实现了某个特定的接口。
(11)因为接口中只含有public static final 常量和public abstract方法,故在写接口的时候可以省略这些关键字。
(12)如果接口的返回类型不是void,那么实现方法体的时候,至少要有一个return语句;如果接口的返回类型是void,可以除了大括号之外可以没有任何语句。
(13)Java提供的接口都在相应的包中,可以通过引入包使用相应的接口;也可以自定义接口,一个源文件就是由类和接口来组成的。
(14)类实现的接口的方法以及接口中的常量可以通过类的对象进行调用,常量也可以通过类名和接口名进行调用。
(15)接口声明的时候,如果加上关键字public,那么接口可以被任一个类进行调用,如果没有public则为友好型接口,只能被同一个包内的类进行调用。
(16)如果父类使用某个接口,那么子类也就使用了接口,不用再使用implements。
(17)接口可以通过extends继承接口。
(18)如果一个类声明实现一个接口但没有实现接口的所有方法,那么这个类一定得是abstract类。
(19)静态方法:从Java SE 8开始,允许在接口中增加静态方法,并给静态方法提供方法体实现,该静态方法只能通过接口名.静态方法
来调用。实现语法只要在方法前面加static关键字即可,这理论上讲是可以的,但这有违于接口作为抽象规范的初衷。静态方法只能被具体实现类继承,不能在实现类中重写。
(20)默认方法:可以为接口方法提供一个默认方法体实现,在方法前加default修饰符即可,这样子类无需重写这个方法也能得到一个接口的默认实现。默认方法也可以被具体实现类重写。在实现类中调用默认方法要使用接口名.super.默认方法来调用。
(21)解决默认方法的冲突:
如果先在一个接口中将一个方法定义为默认方法,然后又在超类或另一个接口中定义了同样的方法,会发生冲突。解决冲突规则如下:
- 超类和接口冲突。如果超类提供了一个具体方法,那么根据超类优先原则,同名而且有相同参数类型的默认方法会被忽略。
- 多接口之间冲突。如果一个实现类实现了多个接口,一个接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否是默认参数)相同的方法,此时就发生了接口冲突,必须在实现类中重写这个方法来解决冲突。
(22)解决重名常量的方法:
1. 超类和接口冲突。如果一个类继承了一个超类和实现了若干接口,此时不像默认方法冲突一样有超类优先原则。只能通过在实现类中覆盖该常量来解决冲突。
2. 多接口之间冲突。如果一个类实现了多个接口,而这些接口又有重名常量,此时会发生冲突。必须用接口名.常量
的方式来精确指明要使用的常量。
(23)Comparator接口:Comparator接口意为"比较器"接口,是一个泛型接口,可用于自定义排序规则和大小比较等。要进行自定义排序,Arrays.sort方法有一个重载版本,需要提供一个数组和一个比较器作为参数。
(24)对象克隆:原变量和副本都会指向同一个对象,这说明,任何一个变量的改变都会影响到另一个变量。如果有一个对象original,希望创建一个对象copy使得其初始状态与original相同,但是之后它们各自回有自己不同的状态,这种情况下就可以使用克隆。clone() 方法并不是 Cloneable 接口的方法,而是 Object 的一个 protected 方法。Cloneable 接口只是规定,如果一个类没有实现 Cloneable 接口又调用了 clone() 方法,就会抛出 CloneNotSupportedException。
(25)接口和抽象类:
区别:
1.接口所有的变量必须是public static final;抽象类的变量无限制
2.接口没有构造方法,不能用new操作符实例化;抽象类有构造方法,由子类通过构造方法链调用,不能用new操作符实例化
3.接口所有方法必须是公共抽象实例方法(Java SE 8开始允许定义静态方法),抽象类无限制
4.一个类只可以继承一个父类,但可以实现多个接口
5.所有的类有一个共同的根Object类,接口没有共同的根
6.抽象类和子类的关系应该是强的“是一种”关系(strong is-a relationship),而接口和子类的关系是弱的"是一种"关系(weak is-a relationship)。接口比抽象类更灵活,因为实现接口的子类只需要具有统一的行为即可,不需要都属于同一个类型的类。
二、lambda表达式:
(1)lambda表达式是一个可传递的代码块,可以在以后执行一次或多次
(2)lambda表达式的语法:
包含三个部分
一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数
一个箭头符号:->
方法体,可以是表达式和代码块,方法体函数式接口里面方法的实现,如果是代码块,则必须用{}来包裹起来,且需要一个return 返回值,但有个例外,若函数式接口里面方法返回值是void,则无需{ }
(3)函数式接口:对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式,这种接口称为函数式接口。
(4)方法引用:其实是lambda表达式的一个简化写法,所引用的方法其实是lambda表达式的方法体实现,语法也很简单,左边是容器(可以是类名,实例名),中间是"::",右边是相应的方法名。
一般方法的引用格式是
如果是静态方法,则是ClassName::methodName。如 Object ::equals
如果是实例方法,则是Instance::methodName。如Object obj=new Object();obj::equals;
构造函数.则是ClassName::new
(5)构造器引用:构造器引用与方法引用类似,只不过方法名为new。例如Employee::new
是Employee构造器的一个引用。至于是哪一个构造器取决于上下文,比如Function<Integer,Employee> func1 = Employee :: new;
就相当于Function<Integer,Employee> func = x -> new Employee(x);
数组类型也有构造器引用,如int[]::new
等价于lambda表达式x -> new int[x]
(6)处理lambda表达式:
我们之前提到,lambda表达式的重点是延迟执行,之所以希望以后再执行代码,有很多原因,如:
1. 在一个单独的线程中运行代码
2. 多次运行代码
3. 在算法的恰当位置运行代码(例如,排序中的比较操作)
4. 发生某种情况时执行代码(如,点击了一个按钮、数据到达等)
5. 只在必要时才运行代码
下面是常用的函数式接口和基本类型的函数式接口:


(7)为什么需要lambda表达式:
主要有三个原因:
1. 更加紧凑的代码
2. 修改方法的能力
3. 更好地支持多核处理
三、内部类:
(1)内部类,或者称为嵌套类,是一个定义在另一个类范围中的类。一个内部类可以如常规类一样使用。通常,在一个类只被它的外部类所使用的时候,才将它定义为内部类,内部类机制主要用于设计具有互相协作关系的类集合。
(2)使用内部类的好处:
1.内部类可以很好地实现隐藏:一般的非内部类,是不允许有 private 与protected权限的,但内部类可以。
2.成员内部类拥有外围类的所有元素的访问权限:内部类可以访问包含它的外部类的所有数据域(包括私有数据域)和方法,没有必要将外部类对象的引用传递给内部类的构造方法,内部类有一个指向外部类对象的隐式引用,如果显式写出,外部类的引用是OuterClass.this。
3.可以间接实现多重继承:比如在A类中定义两个内部类innerClass1和innerClass2分别继承B类和C类,则A类就具有了B类和C类的属性和方法,间接实现了多重继承。
4.减小了类文件编译后的产生的字节码文件的大小。
(3)内部类具有一下特征:
- 一个内部类被编译成一个名为
OuterClassName$InnerClassName
的类。例如,一个定义在Test类中的成员内部类A被编译成Test$A.class
。 - 内部类对象通常在外部类中创建,但是你也可以从另外一个类中来创建一个内部类的对象。如果是成员内部类,你必须先创建一个外部类的实例,然后使用下面的语法创建一个内部类对象:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
如果是静态内部类的,使用下面语法来创建一个内部类对象:OuterClass.InnerClass innerObject = new OuterClass.InnerClass();
(4)局部内部类:可以把内部类定义在一个方法中,称为局部内部类,也叫方法内部类。局部内部类就像是方法里面的一个局部变量一样,不能有public、protected、private以及static修饰符。它的作用域被限定在声明这个局部类的块中。局部类有一个优势,即对外部世界完全隐藏起来。即使外部类中的其他代码也不能访问它。除了其所在的方法之外,没有任何方法知道该局部类的存在。局部内部类只能访问被final修饰的局部变量。
(5)匿名内部类:有时我们在程序中对一个类只使用一次,此时就可以把类的定义和实例化对象整合在一起,来简化对于抽象类和接口实现的操作,这就是匿名内部类。
(6)静态内部类:有时候,使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围类的元素。为此,可以为内部类加上static关键字声明为静态内部类。
静态内部类不持有外部类的引用,只能访问外部类的静态成员变量和方法,而不能访问外部类的非静态成员属性和非静态方法,如果要调用和访问,必须实例化外部类对象。当静态内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的
是静态内部类的成员。如果要访问外部类的非静态同名成员,不能再使用外部类.this.成员
的形式,而是要实例化外部类对象。如果要访问外部类的静态同名成员,可以通过外部类.成员
的方式来访问。
与常规内部类不同,静态内部类可以有静态变量和静态方法。可以通过外部类.内部类.静态成员
方式来访问。
四、代理:
(1)利用代理可以在运行时创建一个实现了一组给定接口的新类。
(2)创建代理对象:
要想创建一个代理对象,需要使用Proxy类的newProxyInstance方法,这个方法有三个参数:
1. 一个类加载器(class loader)
2. 一个class对象数组
3. 一个调用处理器
(3)代理类的特性:
1. 所有的代理类都扩展于Proxy类。
2. 所有的代理类都覆盖了Object类中的方法toString、equals和hashCode。
3. 没有顶定义代理类的名字,Sun虚拟机中的Proxy类将生成一个以字符串$Proxy开头的类名。
4. 代理类一定是public和final。
第二部分:实验部分
实验1:测试程序1(5分)
package interfaces; import java.util.*; /**
* This program demonstrates the use of the Comparable interface.
* @version 1.30 2004-02-27
* @author Cay Horstmann
*/
public class EmployeeSortTest //用EmployeeTest关联Employee
{
public static void main(String[] args)
{
Employee[] staff = new Employee[3]; //定义数组 staff[0] = new Employee("Harry Hacker", 35000);
staff[1] = new Employee("Carl Cracker", 75000);
staff[2] = new Employee("Tony Tester", 38000); Arrays.sort(staff); //进行排序 // print out information about all Employee objects
for (Employee e : staff)
System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
}
}
package interfaces; public class Employee implements Comparable<Employee> //为泛型数组Comparable接口提供一个类型参数
{
private String name;
private double salary; public Employee(String name, double salary)
{
this.name = name;
this.salary = salary;
} public String getName()
{
return name;
} public double getSalary()
{
return salary;
} public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
} /**
* Compares employees by salary
* @param other another Employee object
* @return a negative value if this employee has a lower salary than
* otherObject, 0 if the salaries are the same, a positive value otherwise
*/
public int compareTo(Employee other) //用Employee对象与other进行比较
{
return Double.compare(salary, other.salary); //使用静态Double.compare方法
}
}
程序运行结果如下:
接口中的所有方法自动地属于pubic,在接口中声明方法时,不必提供关键字public。
为了让类实现一个接口,需要:
(1)将类声明为实现给定的接口,使用关键字implements.
(2)对接口中的所有方法进行定义。
comparable接口:类对象之间比较“大小”往往是很有用的操作,比如让对象数组排序时,就需要依赖比较操作。对于不同的类有不同的语义。如Student类,比较2个学生对象可以比较他们的score分数来评判。
Java不支持预算符重载,我们通过实现Comparable接口达到相同的目的。当类实现了Comparable接口,则认为这个类的对象之间是可比较的。
int compareTo(T other)
用这个对象与other进行比较,如果这个对象小于other则返回负值,如果相等则返回0,否则返回正值。
实验1:测试程序2(5分)
程序代码如下:
interface A
{
double g=9.8;
void show( );
}
class C implements A
{
public void show( )
{System.out.println("g="+g);}
}
class InterfaceTest
{
public static void main(String[ ] args)
{
A a=new C( );
a.show( );
System.out.println("g="+C.g);
}
}
运行结果如下:
实验1:测试程序3(5分)
程序代码如下:
package timer; /**
@version 1.02 2017-12-14
@author Cay Horstmann
*/ import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer; public class TimerTest
{
public static void main(String[] args)
{
ActionListener listener = new TimePrinter(); //构造ActionListener listener类的一个对象,并将它传递给Timer构造器 // construct a timer that calls the listener
// once every 10 seconds
Timer t = new Timer(1000, listener);
t.start(); //启动定时器 // keep program running until the user selects "OK"
JOptionPane.showMessageDialog(null, "Quit program?");
System.exit(0);
}
} //定义一个实现ActionListener接口的类
class TimePrinter implements ActionListener //定时器需要知道调用的方法,并要求传递的对象所属的类实现了java。awt.event包中的ActionListener接口
{
public void actionPerformed(ActionEvent event) //当到达指定的时间间隔时,定时器就调用actionPerformed方法
{
System.out.println("At the tone, the time is "
+ new Date());
Toolkit.getDefaultToolkit().beep();
}
}
程序运行结果如下:
回调设计模式:
核心总结:
1.接口作为方法参数,实际传入的是具体的实现类对象
2.A类让B类做一件事情,B做完后告诉A
实验1:测试程序4(5分)
程序代码如下:
package clone; /**
* This program demonstrates cloning.
* @version 1.11 2018-03-16
* @author Cay Horstmann
*/
public class CloneTest
{
public static void main(String[] args) throws CloneNotSupportedException
{
var original = new Employee("John Q. Public", 50000);
original.setHireDay(2000, 1, 1);
Employee copy = original.clone();
copy.raiseSalary(10);
copy.setHireDay(2002, 12, 31);
System.out.println("original=" + original);
System.out.println("copy=" + copy);
}
}
package clone; import java.util.Date;
import java.util.GregorianCalendar; public class Employee implements Cloneable //将克隆定义为public,调用super.clone()
{
private String name;
private double salary;
private Date hireDay; public Employee(String name, double salary)
{
this.name = name;
this.salary = salary;
hireDay = new Date();
}
//创建深拷贝的clone方法
public Employee clone() throws CloneNotSupportedException //声明异常
{
// call Object.clone() 调用对象克隆
Employee cloned = (Employee) super.clone(); // clone mutable fields 克隆易变字段
cloned.hireDay = (Date) hireDay.clone(); return cloned;
} /**
* Set the hire day to a given date.
* @param year the year of the hire day
* @param month the month of the hire day
* @param day the day of the hire day
*/
public void setHireDay(int year, int month, int day)
{
Date newHireDay = new GregorianCalendar(year, month - 1, day).getTime(); // example of instance field mutation
hireDay.setTime(newHireDay.getTime());
} public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
} public String toString()
{
return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
}
}
程序运行结果如下:
1. 对象克隆实现技术:克隆这个词大家并不陌生,实质就是拷贝对象,形成一个对象的副本。克隆对象就是对已有的一个对象进行拷贝。
进行克隆的目的(意义):被克隆和克隆对象之间完全复制、相互之间没有影响的目的。
为什么要使用克隆对象:当我们new一个对象之后是要对该对象进行初始化的,不然这个对象是空的没有内容。而使用克隆,则会得到一个原对象以及原对象里面包含的内容。例如,你有一个User对象,里面的包含了相关的属性。此时你想要修改里面的某一属性,但又不想破坏原对象里面的数据,此时就可以克隆User这个对象,然后在克隆的这个User对象上进行修改操作。除此,如果你在操作完之后判断一下属性是否更改成功,则使用克隆的对象和原对象做一下对比即可。
2.浅拷贝和深拷贝的差别:浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。例如:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2 中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2 中包含对C2(C1的copy)的引用。
若不对clone()方法进行改写,则调用此方法得到的对象即为浅拷贝。
实验2:(10分)
程序代码如下:
package lambda; import java.util.*; import javax.swing.*;
import javax.swing.Timer; /**
* This program demonstrates the use of lambda expressions.
* @version 1.0 2015-05-12
* @author Cay Horstmann
*/
public class LambdaTest
{
public static void main(String[] args)
{
var planets = new String[] { "Mercury", "Venus", "Earth", "Mars",
"Jupiter", "Saturn", "Uranus", "Neptune" };
System.out.println(Arrays.toString(planets));
System.out.println("Sorted in dictionary order:");
Arrays.sort(planets); //调用Arrays类的sort方法
System.out.println(Arrays.toString(planets));
System.out.println("Sorted by length:");
Arrays.sort(planets, (first, second) -> first.length() - second.length()); //lambda表达式
System.out.println(Arrays.toString(planets)); var timer = new Timer(1000, event ->
System.out.println("The time is " + new Date()));
timer.start(); // keep program running until user selects "OK"
JOptionPane.showMessageDialog(null, "Quit program?"); //窗口显示信息"Quit program?"
System.exit(0);
}
}
程序运行结果如下:
lambda表达式的优缺点:
优点:
1. 简洁。
2. 非常容易并行计算。
3. 可能代表未来的编程趋势。
4. 结合 hashmap 的 computeIfAbsent 方法,递归运算非常快。java有针对递归的专门优化。
缺点:
1. 若不用并行计算,很多时候计算速度没有比传统的 for 循环快。(并行计算有时需要预热才显示出效率优势,并行计算目前对 Collection 类型支持的好,对其他类型支持的一般)
2. 不容易调试。
3. 若其他程序员没有学过 lambda 表达式,代码不容易让其他语言的程序员看懂。
4. 在 lambda 语句中强制类型转换貌似不方便,一定要搞清楚到底是 map 还是 mapToDouble 还是 mapToInt
实验3:编程练习(25分)
程序代码如下:
package ID; import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Collections;//对集合进行排序、查找、修改等; public class Main {
private static ArrayList<Citizen> citizenlist; public static void main(String[] args) {
citizenlist = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
File file = new File("D://身份证号.txt");
//异常捕获
try {
FileInputStream fis = new FileInputStream(file);
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
String temp = null;
while ((temp = in.readLine()) != null) { Scanner linescanner = new Scanner(temp); linescanner.useDelimiter(" ");
String name = linescanner.next();
String id = linescanner.next();
String sex = linescanner.next();
String age = linescanner.next();
String birthplace = linescanner.nextLine();
Citizen citizen = new Citizen();
citizen.setName(name);
citizen.setId(id);
citizen.setSex(sex);
// 将字符串转换成10进制数
int ag = Integer.parseInt(age);
citizen.setage(ag);
citizen.setBirthplace(birthplace);
citizenlist.add(citizen); }
} catch (FileNotFoundException e) {
System.out.println("信息文件找不到");
e.printStackTrace();
} catch (IOException e) {
System.out.println("信息文件读取错误");
e.printStackTrace();
}
boolean isTrue = true;
while (isTrue) { System.out.println("1.按姓名字典序输出人员信息");
System.out.println("2.查询最大年龄的人员信息、查询最小年龄人员信息");
System.out.println("3.查询人员中是否有你的同乡");
System.out.println("4.输入你的年龄,查询文件中年龄与你最近人的姓名、身份证号、年龄、性别和出生地");
System.out.println("5.退出");
int nextInt = scanner.nextInt();
switch (nextInt) {
case 1:
Collections.sort(citizenlist);
System.out.println(citizenlist.toString());
break;
case 2:
int max = 0, min = 100;
int m, k1 = 0, k2 = 0;
for (int i = 1; i < citizenlist.size(); i++) {
m = citizenlist.get(i).getage();
if (m > max) {
max = m;
k1 = i;
}
if (m < min) {
min = m;
k2 = i;
}
}
System.out.println("年龄最大:" + citizenlist.get(k1));
System.out.println("年龄最小:" + citizenlist.get(k2));
break;
case 3:
System.out.println("出生地:");
String find = scanner.next();
String place = find.substring(0, 3);
for (int i = 0; i < citizenlist.size(); i++) {
if (citizenlist.get(i).getBirthplace().substring(1, 4).equals(place))
System.out.println("出生地" + citizenlist.get(i));
}
break;
case 4:
System.out.println("年龄:");
int yourage = scanner.nextInt();
int near = peer(yourage);
int j = yourage - citizenlist.get(near).getage();
System.out.println("" + citizenlist.get(near));
break;
case 5:
isTrue = false;
System.out.println("程序已退出!");
break;
default:
System.out.println("输入有误");
}
}
} public static int peer(int age) {
int flag = 0;
int min = 53, j = 0;
for (int i = 0; i < citizenlist.size(); i++) {
j = citizenlist.get(i).getage() - age;
if (j < 0)
j = -j;
if (j < min) {
min = j;
flag = i;
}
}
return flag;
}
}
package ID;
public class Citizen implements Comparable<Citizen> { private String name;
private String id;
private String sex;
private int age;
private String birthplace; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public int getage() {
return age;
} public void setage(int age) {
this.age = age;
} public String getBirthplace() {
return birthplace;
} public void setBirthplace(String birthplace) {
this.birthplace = birthplace;
} public int compareTo(Citizen other) {
return this.name.compareTo(other.getName());
} public String toString() {
return name + "\t" + sex + "\t" + age + "\t" + id + "\t" + birthplace + "\n";
}
}
程序运行结果如下:
实验总结:(10分)
通过这周的实验学习,初步掌握了接口的一些简单知识:接口本身就是一个特殊的类;接口不能实例化(不能new,但是可是使用多态去进行实例化);接口的子类可以是抽象类,也可以是具体类(重写接口类里的所有方法);接口的成员变量(默认是常量):成员特点:只能是常量,并且是静态,因为默认情况下接口成员变量的修饰符是:public static final;构造方法:接口没有构造方法;成员方法:只能是抽象方法,其中默认修饰符是:public abstract ; 注意:抽象方法中不能有主题;接口不能创建对象;接口没有构造方法;因为接口是提供给类使用,当非抽象类去实现一个接口时,必须把接口中所有方法都实现。还了解了lambda表达式的用法及优缺点,为什么要使用lambda表达式。
201871010116-祁英红《面向对象程序设计(java)》第八周学习总结的更多相关文章
- 201771010134杨其菊《面向对象程序设计java》第九周学习总结
第九周学习总结 第一部分:理论知识 异常.断言和调试.日志 1.捕获 ...
- 201871010132-张潇潇《面向对象程序设计(java)》第一周学习总结
面向对象程序设计(Java) 博文正文开头 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cn ...
- 扎西平措 201571030332《面向对象程序设计 Java 》第一周学习总结
<面向对象程序设计(java)>第一周学习总结 正文开头: 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 ...
- 杨其菊201771010134《面向对象程序设计Java》第二周学习总结
第三章 Java基本程序设计结构 第一部分:(理论知识部分) 本章主要学习:基本内容:数据类型:变量:运算符:类型转换,字符串,输入输出,控制流程,大数值以及数组. 1.基本概念: 1)标识符:由字母 ...
- 201871010124 王生涛《面向对象程序设计JAVA》第一周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://edu.cnblogs.com/campus/xbsf/ ...
- 201871010115——马北《面向对象程序设计JAVA》第二周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- 201777010217-金云馨《面向对象程序设计(Java)》第二周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- 201871010132——张潇潇《面向对象程序设计JAVA》第二周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- 201771010123汪慧和《面向对象程序设计Java》第二周学习总结
一.理论知识部分 1.标识符由字母.下划线.美元符号和数字组成, 且第一个符号不能为数字.标识符可用作: 类名.变量名.方法名.数组名.文件名等.第二部分:理论知识学习部分 2.关键字就是Java语言 ...
- 20165235 祁瑛 2018-4 《Java程序设计》第八周学习总结
20165235 祁瑛 2018-4 <Java程序设计>第八周学习总结 教材学习内容总结 操作系统与进程 程序是一段静态的代码,它是应用软件执行的蓝本.进程是程序的一次动态执行过程,它对 ...
随机推荐
- 6.Ansible Roles角色实战
==Roles小技巧:== 1.创建roles目录结构,手动或使用ansible-galaxy init test roles 2.编写roles的功能,也就是tasks. nginx rsyncd ...
- swift为什么不是do while?
swift为什么不是do while do while已经深入人心之后,对repeat while的语义逻辑该如何接受呢? do while的语义逻辑是:这个whilte循环先执行一次.逻辑目标针对w ...
- MySQL数据库~~~~~查询行(文件的内容)
1. 单表查询 语法 select distinct 字段 from 库名.表名 where 条件 group by 字段 # 分组 having 筛选 # 过滤 order by 字段 # 排序 l ...
- Shell批量SSH免交互登录认证
脚本实现功能:批量或单个SSH免交互登录认证 脚本应用场景:当部署集群时,大多数实现要配置好管理节点与从节点的SSH免交互登录,针对这样的情况,写了下面脚本,简化工作. 脚本支持系统:Ubuntu和C ...
- shell 脚本里的$(( ))、$( )、``与${ }的区别
shell 脚本里的命令执行 1. 在bash中,$( )与` `(反引号)都是用来作命令替换的. 命令替换与变量替换差不多,都是用来重组命令行的,先完成引号里的命令行,然后将其结果替换出来,再重组 ...
- 在mysql中如何写注释
MySql--三种注释写法 #这是注释/*注释内容*/ -- 注释 (--与注释内容之间必须加空格)
- java之匿名内部类
Person.java package insof; public class Person extends Object{ String name; static int age; public P ...
- Ubuntu16.04重装NVIDIA驱动
Ubuntu系统 $ sudo apt update $ sudo apt upgrade 之后出现显卡驱动出现故障,nvidia-smi输出有错,检测不到相应的驱动.只好重装,记录一下,太多的教程根 ...
- Mac-无法进入mysql,你这样做就对了
mysql -uroot -p 输入密码之后报错:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using passwo ...
- Vue 路由导航解析流程
Vue Router完整的导航解析流程