本周主要学习了内部类和匿名类、接口、异常、Comparable接口和Comparator接口、枚举、单例模式。
内部类是指将一个类定义在另一类里面,这个类就是内部类。
package structure;
public class Inner {
static class B{
void show(){
System.out.println("我是内部类");
}
}
void call(B b){
b.show();
}
public static void main(String[] args) {
Inner inner=new Inner();
inner.call(new B());
}
}
匿名类( Anonymous Class )就是没有名称的类。
package structure;
public abstract class Pet {
public abstract void cry();
//匿名类
Pet pet = new Pet() {
@Override
public void cry() {
System.out.println("喵喵喵");
}
};
}
约定好规范,然后按照规范来做。接口就是定义规范。
package structure;
public interface USB extends IA,IB{
//声明变量,默认是公共的静态常量
int A=0;
}
interface USBC extends USB{
}
interface IA{
void a();
}
interface IB{
void a();
void b();
}
package structure;
public class Main {
public static void main(String[] args) {
Person1 person=new Person1();
try {
person.setName("扈三娘");
person.setAge(18);
person.setGender("男女");
person.print();
}catch (GenderException e){
e.printStackTrace();
}
}
}
//自定义异常类
class GenderException extends Exception{
public GenderException(String message){
super(message);
}
}
class Person1{
private String name="";
private int age=0;
private String gender="男";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) throws GenderException{
if ("男".equals(gender)||"女".equals(gender)){
this.gender = gender;
}else {
throw new GenderException("性别必须是男或女!");
}
}
public void print(){
System.out.println("姓名:"+this.name+"性别:"+this.gender+"年龄:"+this.age);
}
}
package structure;
import java.util.Arrays;
import java.util.Comparator;
/**
* 对象之间的比较, 通过实现Comparable接口, 重写compareTo方法
*
* Comparable接口表示自然比较。 特点:
* 1. 实现Comparable接口的类, 可以比较大小
* 2. 实现Comparable接口的类, 可以进行自然排序
* 自然排序: 从小到大排序
* 自定义排序: 按照自定义的规则排序
* 3. 实现Comparable接口的类, 要重写compareTo方法
* compareTo方法表示比较规则,参数是Object类型, 返回值是 int 类型。
* 返回值是int类型, 有三种情况: 正数, 0, 负数 。
*
* Comparator接口表示比较器。 特点:
* 1. 实现Comparator接口的类, 可以比较两个对象的大小
* 2. 实现Comparator接口的类, 可以进行自定义排序
* 重写compare方法, 比较两个对象的大小
* 返回值是int类型, 有三种情况: 正数, 0, 负数 。
*/
public class Demo2 {
public static void main(String[] args) {
Student[] stu={
new Student("张三",23,90),
new Student("李四",24,80),
new Student("王五",23,70),
new Student("赵六", 24, 80),
new Student("田七", 25, 50)
};
// sort(stu);
Comparator c=new StudentComparator();
// int n= Objects.compare(stu[0],stu[1],c);
// c.compare(stu[0],stu[1]);
// System.out.println(n);
// Arrays.sort 对对象数组进行排序时,对象必须实现 Comparable 接口
// Arrays.sort(stu);
// Arrays.sort(stu, new Comparator<Student>() {
// @Override
// public int compare(Student o1, Student o2) {
// if (o1.getAge()>o2.getAge()){
// return 1;
// }else if (o1.getAge()< o2.getAge()){
// return -1;
// }
// return 0;
// }
// });
//lambda
Arrays.sort(stu,(o1,o2)->{
if (o1.getAge()>o2.getAge()){
return 1;
}else if (o1.getAge()<o2.getAge()){
return -1;
}else {
return 0;
}
});
for (int i = 0; i < stu.length; i++) {
System.out.println(stu[i]);
}
}
private static void sort(Student[] stu) {
for (int i = 0; i < stu.length-1; i++) {
for (int j = 0; j < stu.length-1-i; j++) {
if (stu[j].compareTo(stu[j+1])>0){
Student temp=stu[j];
stu[j]=stu[j+1];
stu[j+1]=temp;
}
}
}
}
}
class Student implements Comparable{
private String name;
private int age;
private int score;
public Student(){
super();
}
public Student(String name,int age,int score){
super();
this.name=name;
this.age=age;
this.score=score;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getScore() {
return score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
/**
* 重写compareTO方法
* 比较两个对象的大小
* 0:相等,1:当前对象大于o,-1:当前对象小于o
* @param o the object to be compared.
* @return
* @throws RuntimeException
*/
@Override
public int compareTo(Object o) throws RuntimeException{
//判断o是不是Student类型
if (o instanceof Student student){
//比较年龄
if (this.age>student.age){
return 1;
}else if (this.age< student.age){
return -1;
}
//比较成绩
if (this.score> student.score){
return 1;
}else if (this.score<student.score){
return -1;
}
//比较姓名
return this.name.compareTo(student.name);
}
//不是就抛出异常
throw new CompareException("类型不匹配");
}
}
/**
* 创建一个Student比较器
*/
class StudentComparator implements Comparator{
/**
* 比较两个 Student 对象的大小
* @param o1 the first object to be compared.
* @param o2 the second object to be compared.
* @return
*/
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Student student&&o2 instanceof Student student1){
//比较年龄
if (student.getAge()>student1.getAge()){
return 1;
}else if (student.getAge()<student1.getAge()){
return -1;
}
//比较成绩
if (student.getScore()>student1.getScore()){
return 1;
}else if (student.getScore()<student1.getScore()){
return -1;
}
//比较姓名
return student.getName().compareTo(student1.getName());
}
throw new CompareException("类型不匹配");
}
}
/**
* 自定义异常
*/
class CompareException extends RuntimeException{
public CompareException(){
super();
}
public CompareException(String message){
super(message);
}
}
天然的单例模式。不能被实例化,每一个实例都声明在枚举中。
package structure;
public enum Gender {
MAN("男"),WOMEN("女");
private String text;
Gender(String text){
this.text=text;
}
public String getText(){
return this.text;
}
}
class Text{
public static void main(String[] args) {
Gender gender=Gender.WOMEN;
System.out.println(gender.getText());
}
}
共有四种单例模式。
package structure;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 单例模式
* 单实例,在项目中只有一个实例。
* 步骤:
* 1. 构造方法私有(private)
* 2. 提供获取唯一实例的方式
*/
public class Singleton {
//饿汉
private static final Singleton SINGLETON=new Singleton();
//构造方法私有
private Singleton(){
if (SINGLETON!=null){
throw new RuntimeException("已有实例");
}
}
public static Singleton getInstance(){
return SINGLETON;
}
}
//懒汉
class LazySingleton{
private static LazySingleton SINGLETON;
private LazySingleton(){}
public static LazySingleton getInstance(){
if (SINGLETON==null){
SINGLETON=new LazySingleton();
}
return SINGLETON;
}
}
//枚举
enum EnumSingleton{
SINGLETON;
}
//静态嵌套类
class Outclass{
private Outclass(){
if (StaticNestedClass.OUTCLASS!=null){
throw new RuntimeException("已有实例");
}
}
//静态嵌套类
public static class StaticNestedClass{
private static final Outclass OUTCLASS=new Outclass();
}
public static Outclass getInstance(){
return StaticNestedClass.OUTCLASS;
}
}
class Test1{
public static void main(String[] args) {
Singleton instance=Singleton.getInstance();
Outclass s=Outclass.getInstance();
Outclass s1=Outclass.getInstance();
System.out.println(s);
System.out.println(s1);
System.out.println(s==s1);
//反射,运行时获取类信息
try {
Constructor<Singleton> c=Singleton.class.getDeclaredConstructor();
c.setAccessible(true);
Singleton singleton=c.newInstance();
System.out.println(instance);
System.out.println(singleton);
System.out.println(instance==singleton);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
周六下午很荣幸跟同学们分享了一下学习方式,也学习到了很多其他同学的学习经验,听到了很多身边同学心里的真实想法。就自己感觉,学不好的主要原因还是压力太大,不够用心,上课容易思想抛锚,对比自身的情况,感觉自己还是好很多,没有太大的压力,每天也很开心,没有想太多的事情,希望自己可以一直这么坚持下去,尽自己最大的努力获得最多的知识。
下周一定要认真努力仔仔细细学习,下周《第八个嫌疑人》要播了,一定要去看!
结合这周的考试,感觉自己对以下的问题还是区分不够清楚:
不管是使用基本数据类型作为参数还是使用对象作为参数,都是值传递;
在Java中,使用引用数据类型作为参数时,实际上是传递了该对象的引用(内存地址)。这意味着在方法中对该引用所指向的对象进行的任何修改都会影响到原始对象。当你将引用数据类型作为参数传递给一个方法时,方法内部可以通过该引用来访问和修改对象的属性和方法。这样做允许你对对象进行更复杂的操作,而不仅仅是传递简单的数值。
需要注意的是,虽然方法内部可以修改对象的属性和方法,但对于引用对象本身的重新赋值不会影响原始对象。也就是说,在方法中将一个新的对象赋值给传入的引用参数,不会改变原始对象的引用。
public class Example {
public static void main(String[] args) {
Person person = new Person("John");
System.out.println("Before calling method: " + person.getName());
changeName(person);
System.out.println("After calling method: " + person.getName());
}
public static void changeName(Person p) {
p.setName("Alice");
}
}
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
①final:final关键字用于表示一个变量、方法或类是不可变的。由于接口是被设计为可被继承的,所以不能用final修饰接口。
②private:private关键字用于表示一个成员(变量、方法或内部类)只能在当前类内部访问,不能被外部类或子类访问。由于接口的成员默认是public访问权限,所以不能用private修饰接口。
③protected:同上。
④static:static关键字用于表示一个成员(变量或方法)属于类本身,而不属于类的实例。由于接口的成员默认是public和abstract的,不能用static修饰接口。
接口不能有构造方法,抽象类可以有构造方法。
接口中的类方法可以直接通过接口名调用,无需实现接口的类进行继承或实现。
抽象类中的类方法可以通过抽象类名调用,也可以通过具体实现了抽象类的子类名调用。
一个类可以实现多个接口,但只能继承一个抽象类。
在Java中,catch块的顺序非常重要,应该从最具体的异常类型到最一般的异常类型进行捕获。在这种情况下,将catch (Exception e)
放在第一个位置是不正确的,因为它是最一般的异常类型,会捕获所有的异常,包括ArithmeticException
。
package structure;
public class Inner1 {
public static void main(String[] args) {
try {
int x = 0;
int y = 5 / x;
} catch (ArithmeticException ae) {
System.out.println("ArithmeticException");
} catch (Exception e) {
System.out.println("Exception");
}
System.out.println("finished");
}
}
在Java中,变量的作用域是在其声明的代码块内部。在这种情况下,变量i
的作用域仅限于for循环内部,无法在循环外部访问。
在Java接口中,不能定义私有属性。接口中的字段默认是常量(final),且必须是公共的(public static final)。
在Java中,子类不一定必须覆盖超类的抽象方法。具体取决于子类是否为抽象类。
如果一个类继承了抽象类,那么它必须实现(覆盖)抽象类中的所有抽象方法,除非它自己也声明为抽象类。如果一个子类是抽象类,那么它可以选择性地实现(覆盖)超类的抽象方法。
public class Main {
public static void main(String[] args) {
String str = "3.14";
float floatValue = Float.parseFloat(str);
System.out.println(floatValue); // 输出:3.14
}
}
package structure;
abstract class Inner1 {
abstract float getFloat();
public class AbstractTest extends Inner1{
private float f1=1.0f;
@Override
float getFloat() {
return f1;
}
}
}
接口中定义的变量被final修饰,不能被修改。
powered by kaifamiao