WWW.YOUINFO.SITE
标签聚合 总贴

/tag/总贴

LinuxDo 最新话题 · 2026-06-11 10:54:19+08:00 · tech

其他内容参见 JAVA学习记录总贴 本期是oop的简单练习,确实都很简单,主要负责熟手 第一题 public static void main(String[] args) { Car c = new Car(); Car car = new Car(100); System.out.println(c); System.out.println(car); } ​ class Car { double price = 10; static String color = "white"; ​ public String toString() { return price + "\t" + color; } ​ public Car(){ this.price = 9; this.color = "black"; } ​ public Car(double price){ this.price = price; } } 答案: 9.0 black 100.0 black 分析: 这道题应该挺好理解的。 ​ 注意 color 是一个静态变量,在第一次 new Car 的时候,static变量 就已经被修改了。 ​ 所以,最后两个实例的静态变量都是 black。 第二题 不难,纯粹练手 在Frock类中声明私有的静态属性currentNum[int类型],初始值为100000,作为衣服出厂的序列号起始值。 声明公有的静态方法getNextNum,作为生成上衣唯一序列号的方法。每调用一次,将currentNum增加100,并作为返回值。 在Homework02类的main方法中,分两次调用getNextNum方法,获取序列号并打印输出。 在Frock类中声明serialNumber(序列号)属性,并提供对应的get方法。 在Frock类的构造器中,通过调用getNextNum方法为Frock对象获取唯一序列号,赋给serialNumber属性。 在Homework02类的main方法中,分别创建三个Frock 对象,并打印三个对象的序列号,验证是否为按100递增。 答案: package hspedu.homework; ​ public class Homework02 { public static void main(String[] args) { System.out.println(Frock.getNextNum()); System.out.println(Frock.getNextNum()); ​ Frock f1 = new Frock(); System.out.println(f1.getSerialNumber()); ​ Frock f2 = new Frock(); System.out.println(f2.getSerialNumber()); ​ Frock f3 = new Frock(); System.out.println(f3.getSerialNumber()); } } ​ class Frock { private static int currentNum = 100000; private int serialNumber; ​ public static int getNextNum() { currentNum += 100; return currentNum; } ​ public Frock() { serialNumber = getNextNum(); } ​ public int getSerialNumber() { return serialNumber; } } 第三题 一个简单的多态练习,题干如下 动物类Animal包含了抽象方法 shout(); Cat类继承了Animal,并实现方法shout,打印“猫会喵喵叫” Dog类继承了Animal,并实现方法shout,打印“狗会汪汪叫” 在测试类中实例化对象Animal cat = new Cat(),并调用cat的shout方法 在测试类中实例化对象Animal dog = new Dog(),并调用dog的shout方法 答案: public class Homework03 { public static void main(String[] args) { Animal cat = new Cat(); cat.shout(); Animal dog = new Dog(); dog.shout(); } } ​ abstract class Animal{ abstract void shout(); } ​ class Cat extends Animal{ @Override void shout() { System.out.println("猫会喵喵叫"); } } ​ class Dog extends Animal{ @Override void shout() { System.out.println("狗会汪汪叫"); } } 第四题 计算器接口具有 work 方法,功能是运算,有一个手机类 Cellphone,定义方法 testWork 测试计算功能,调用计算接口的 work 方法 要求调用 CellPhone 对象 的 testWork 方法,使用上匿名内部类 答案: ps:设计匿名内部类,建议还是认真写一下 public class Homework04 { public static void main(String[] args) { Cellphone cellphone = new Cellphone(); Calculator cal = new Calculator() { @Override public void work(int a, int b) { System.out.println(a + b); } }; cellphone.testWork(cal, 7, 8); } } ​ interface Calculator { void work(int a, int b); } ​ class Cellphone { public void testWork(Calculator calculator, int a, int b) { System.out.println("测试计算功能"); calculator.work(a, b); } } 第五题 编一个类 A,在类中定义局部内部类 B,B 中有一个私有常量 name,有一个方法 show () 打印常量 name。进行测试 进阶:A 中也定义一个私有的变量 name,在 show 方法中打印测试 答案:a piece of cake public class Homework05 { public static void main(String[] args) { new A().new B().show(); } } ​ class A{ private final String name = "AAA"; class B{ private final String name = "BBB"; public void show(){ System.out.println(name); System.out.println(A.this.name); } } } 第六题 有一个交通工具接口类Vehicles,有work接口 有Horse类和Boat类分别实现Vehicles 创建交通工具工厂类,有两个方法分别获得交通工具Horse和Boat 有Person类,有name和Vehicles属性,在构造器中为两个属性赋值 实例化Person对象“唐僧”,要求一般情况下用Horse作为交通工具,遇到大河时用Boat作为交通工具 额外:使用匿名内部类,增加一个用飞机过火焰山的方法,因为只用一次,因此不要写一个新的类 答案: public class Homework06 { public static void main(String[] args) { Person tang = new Person("唐僧", null); tang.passRiver(); tang.common(); tang.passRiver(); tang.passMountain(); } } ​ interface Vehicles { void work(); } ​ class Horse implements Vehicles { @Override public void work() { System.out.println("horse is working"); } } ​ class Boat implements Vehicles { @Override public void work() { System.out.println("boat is working"); } } ​ class Plane implements Vehicles { @Override public void work() { System.out.println("plane is working"); } } ​ class Factory { private static final Horse HORSE = new Horse(); private static final Boat BOAT = new Boat(); private static final Plane PLANE = new Plane(); ​ public static Horse getHorse() { return HORSE; } ​ public static Boat getBoat() { return BOAT; } ​ public static Plane getPlane() { return PLANE; } } ​ class Person { private String name; private Vehicles vehicle; ​ public Person(String name, Vehicles vehicle) { this.name = name; this.vehicle = vehicle; } ​ public void setVehicle(Vehicles vehicle) { this.vehicle = vehicle; } ​ ​ public void passRiver() { if (!(vehicle instanceof Boat)) { vehicle = Factory.getBoat(); } vehicle.work(); } ​ public void common() { if (!(vehicle instanceof Horse)) { vehicle = Factory.getHorse(); } vehicle.work(); } ​ public void passMountain() { vehicle = new Vehicles(){ @Override public void work() { System.out.println("plane is working"); } }; vehicle.work(); } } 简要分析: 用懒汉式单例,保证只创建一个船和马对象,节省资源 用 vehicle instanceof Horse 来判断具体情况 第七题 有一个 Car 类,有属性 temperature(温度),车内有 Air(空调)类,有吹风的功能 flow,Air 会监视车内的温度,如果温度超过 40 度则吹冷气。如果温度低于 0 度则吹暖气,如果在这之间则关掉空调。实例化具有不同温度的 Car 对象,调用空调的 flow 方法,测试空调吹的风是否正确。 public class Homework07 { public static void main(String[] args) { Car car = new Car(42); Car.Air air = car.getAir(); air.flow(); Car car1 = new Car(2); Car.Air air1 = car1.getAir(); air1.flow(); Car car2 = new Car(-1); Car.Air air2 = car2.getAir(); air2.flow(); } } ​ class Car{ private double temperature; ​ public Car(double temperature) { this.temperature = temperature; } ​ class Air{ public void flow(){ if(temperature > 40){ System.out.println("吹冷风"); } else if(temperature < 0){ System.out.println("吹暖风"); } else { System.out.println("关闭空调"); } } } ​ public Air getAir(){ return new Air(); } } 第八题 创建一个Color枚举类 有 RED,BLUE,BLACK,YELLOW,GREEN这五个枚举值/对象; Color有三个属性redValue, greenValue, blueValue, 创建构造方法,参数包括这三个属性, 每个枚举值都要给这三个属性赋值,三个属性对应的值分别是 red: 255,0,0 blue:0,0,255 black:0,0,0 yellow:255,255,0 green:0,255,0 定义接口,里面有方法show,要求Color实现该接口 show方法中显示三属性的值 将枚举对象在switch语句中匹配使用 1 个帖子 - 1 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-06-09 15:49:25+08:00 · tech

我的其他笔记可以查看 JAVA学习记录总贴 内部类 基础知识 内部类的类的第五大成员。 五大成员分别是:属性、方法、构造器、代码块、内部类。 定义:一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为“内部类”,在外面的类称为“外部类”,内部类最大的特点就是可以访问私有属性,并且可以体现类与类之间的包含关系。 语法 class Outer{//外部类 class Inter{//内部类 } } class OtherOuter{//外部其他类 } PS:内部类是OOP的重难点,底层源码有大量的内部类,必须要要下来这一块。 分类 定义在外部类局部位置(比如方法内) 局部内部类(有类名) 匿名内部类(无类名,重点!!!!!!!) 定义在外部类的成员位置上 成员内部类(没用static) 静态内部类(使用static) class OuterClass { //成员内部类 class MemberInnerClass {} //静态内部类 static class StaticInnerClass{} //外部方法 public void outerMethod() { //局部内部类 class LocalInnerClass {} ​ //匿名内部类 Runnable runnable = new Runnable() { @Override public void run() { System.out.println("匿名内部类"); } }; runnable.run(); } } 局部内部类 细节 局部内部类定义在外部类的局部位置,比如在方法中,并且有类名。(代码块中也行,但罕见) 可以直接访问外部类的所有成员,包含私有的 不能添加访问修饰符,因为局部内部类本质上就是一个局部变量,局部变量不能使用修饰符,同理它也不能,但它可以使用final,因为局部变量也可以用final,顺带一提abstract也可以。 局部内部类是可以被继承的。 作用域:仅仅作用在定义它的方法或代码块中 局部内部类想访问外部类的成员,直接访问即可 外部类想访问局部内部类的成员,可以在作用域内实例化局部内部类,但是注意,必须在定义它之后再new 外部其他类不可能访问局部内部类,这个挺好理解,因为局部内部类本质局部变量,不在它作用域内。 如果外部类和局部内部类变量重名,则会遵循就近原则,优先访问到局部内部类的变量,如果想要访问外部类的成员,则用如下语法 外部类类名.this.成员名 ,ps:顺带一提,如果你不嫌脱裤子放屁,其实 外部类类名.this.成员名 这种语法,可以在类的所有地方精确调用到本类成员 再顺带一提,其实所有内部类都可以在内部继续写内部类,这也是它复杂的原因 class OuterClass { private int n1 = 10; private void m2() {} ​ public void m1() { class InnerClass { public void show() { // 可以直接访问外部类的所有成员,包括私有类型,包括方法 System.out.println("n1 = " + n1); m2(); } } class A extends InnerClass{ } InnerClass innerClass = new InnerClass(); } } 建议对着上面的代码,每一条细节都去自己实践一遍,看看违反了会报什么错。 匿名内部类 重点中的重点,这部分所有代码建议自己真的看完书去手敲一下,不要指望看一遍能懂,更不要单纯相信遇到的时候让AI来解释就好,没那么轻松。 特点 本质是类,底层会有独立的class字节码文件 属于内部类,定义在外部类/代码块,这类局部位置中 没有类名,其实底层是有的,但是程序员不关心,因而匿名 同时也是一个对象,类定义好的同时就已经被创建了 基本语法 new 父类/接口名(构造参数列表){ // 类体:重写父类/实现接口的抽象方法,也可以新增自定义成员 }; 基于接口的匿名内部类 class Outer04 { private int n1 = 10; ​ public void method() { // 基于接口的匿名内部类 // 1. 需求:使用IA接口,并创建对象 // 2. 传统方法是写一个类,实现接口,创建对象,并调用方法 // 3. 但如果我们的需求是,这个类只用一次,那么定义出来就有些浪费了,所以我们可以使用匿名内部类来简化开发 // inner的编译类型是IA,而inner的运行类型是匿名内部类 /*其实这里的底层含义是 class Outer04$1 implements IA { @Override public void cry() { System.out.println("匿名内部类实现了cry方法"); } } */ // 4. jdk底层创建了匿名内部类Outer04$1,然后创建了实例,并且把地址返回给inner // 5. 匿名内部类只能使用一次,不能再次使用 IA inner = new IA(){ @Override public void cry() { System.out.println("匿名内部类实现了cry方法"); } }; inner.cry(); System.out.println(inner.getClass()); IA inner1 = new IA(){ @Override public void cry() { System.out.println("匿名内部类实现了cry方法"); } }; System.out.println(inner1.getClass()); } } ​ interface IA { public void cry(); } 值得说的细节在注释里都已经写明了,我在此补充一点 Outer04$1 就是 JVM 自动为第一个匿名内部类分配的名字,数字表示该类在外部类中出现的顺序。 基于类的匿名内部类 class Outer04 { private int n1 = 10; public void method() { Father fa = new Father("张三"); Father fa1 = new Father("张三"){}; // 证明匿名类创建的不是Father类,而是匿名内部类 System.out.println(fa.getClass()); System.out.println(fa1.getClass()); Father fa2 = new Father("张三"){ @Override public void show() { System.out.println("匿名内部类重写show()"); } }; fa2.show(); ​ Animal animal = new Animal() { @Override public void eat() { System.out.println("匿名内部类重写eat()"); } }; animal.eat(); } } ​ class Father { private String name; public Father(String name) { this.name = name; } public void show() { System.out.println("show()"); } } ​ abstract class Animal{ public abstract void eat(); } 简单总结一些要点 匿名内部类可以重写方法 父类的构造器如果有参数,则你也要提供对应参数(如果有多个构造器,那你就提供符合其中一个的就行) 基于抽象类(接口)的匿名内部类,必须实现其中所有抽象方法 一些细节 匿名内部类,既有定义一个类的特性,也有创建对象的特性,是一个凉面派 可以直接访问外部类的所有成员,包括外部私有成员 不能添加访问修饰符(直觉看上去也没办法提交orz),因为它本质是局部变量 作用域仅在定义它的方法or代码块中 外部其他类也不能访问匿名内部类,因为其本质局部变量 如果外部类和匿名内部类变量重名,则会遵循就近原则,优先访问到局部内部类的变量,如果想要访问外部类的成员,则用如下语法 外部类类名.this.成员名 匿名内部类练习 题目1:写一个基于接口的匿名内部类,并把它作为方法参数传入 public class AnonymousClass { public static void main(String[] args) { // 方式1:直接在参数位置编写匿名内部类 f1(new AA() { @Override public void show() { System.out.println("匿名类实现接口"); } }); // 方式2:先创建匿名内部类对象,再传入参数 AA aa = new AA() { @Override public void show() { System.out.println("匿名类实现接口"); } }; f1(aa); } public static void f1(AA aa){ aa.show(); } } ​ interface AA{ void show(); } 题目2: 定义一个铃声接口 Bell,接口中包含 ring() 方法。 定义一个手机类 Cellphone,类中包含闹钟功能方法 alarmclock(Bell bell),方法的参数类型为 Bell。 测试手机类的闹钟功能:通过匿名内部类创建 Bell 接口的实现对象,作为参数传入 alarmclock 方法,调用 ring() 方法时打印:懒猪起床了。 再传入另一个匿名内部类对象,调用 ring() 方法时打印:小伙伴上课了。 public class AnonymousClass { public static void main(String[] args) { new Cellphone().alarmclock(new Bell() { @Override public void ring() { System.out.println("懒猪起床了"); } }); new Cellphone().alarmclock(new Bell() { @Override public void ring() { System.out.println("小伙伴上课了"); } }); } } interface Bell { void ring(); } class Cellphone { public void alarmclock(Bell bell){ bell.ring(); } } 重点:一定要写一写感受一下,这部分涉及:多态、继承、动态绑定、内部类,多个知识点混杂在一起,需要认真练习 成员内部类 成员内部类定义在外部类的成员位置,并且没有static修饰 可以访问外部类的所有成员 可以添加任意的修饰符,因为其地位相当于一个成员 成员内部类的作用域和外部类的其他成员一样,都是整个类体。 成员内部类可以调用外部类的所有成员,包括私有。 外部类可以访问成员内部类的所有成员,包括私有成员,不过,必须要创建实例才能访问。 外部其他类想要访问成员内部类,有两种方法,分别标注在代码里了 如果外部类和内部类成员同名,则内部类访问时采取就近原则,如果一定要访问外部类的同名成员,则采用 外部类.this.成员名 的方式 public class AnonymousClass { public static void main(String[] args) { // 外部其他类访问成员内部类的两种方式 // 方式一 通过外部类对象访问成员内部类对象,下面的两种写法本质上是等价的 Outer.Inner inner = new Outer().new Inner(); // 写法1 Outer outer = new Outer(); // 写法2 Outer.Inner inner1 = outer.new Inner(); // 方式二 在外部类中编写一个写法,返回成员内部类对象 Outer.Inner inner2 = outer.getInner(); } } class Outer{ private int n1 = 10; private String name = "张三"; public Inner getInner(){ return new Inner(); } // 成员内部类 // 成员内部类是定义在外部类的成员位置上 public class Inner{ private int n2 = 20; public void say(){ System.out.println("n1 = " + n1 + " name = " + name); } } public void show(){ Inner inner = new Inner(); // 即使是类内部的私有成员也可以被访问,因为本质上它也是类的一部分。 System.out.println(inner.n2); } } 静态内部类 静态内部类定义在外部类的成员位置,并且有 static 修饰符。 静态内部类可以直接访问外部类的所有静态成员(包括私有的),但是不能直接访问非静态成员;可以访问本类的所有成员,不管是静态还是非静态 解释: 静态内部类是外部类的一部分,因而可以访问外部类的所有静态成员。 对于外部类的非静态成员,可以在静态内部类中实例化,然后访问。 可以添加任意访问修饰符,因为它的地位就是一个成员 作用域和其他的成员一样,是整个类体内部。 静态内部类可以在不依赖外部类的前提下被实例化 外部其他类访问静态内部类、静态内部类访问外部类、外部类访问静态内部类的逻辑都写在了代码里,如下所示 外部类和静态内部类成员重名时,静态内部类如果想要访问,则默认就近原则,如果想要访问外部类的同名成员,则需要 外部类名.成员 P.S. 内部类可以是静态的,但是顶层类不能是静态的。 public class AnonymousClass { public static void main(String[] args) { // 展示外部其它类访问静态内部类的方式 // 方式1,直接new Outer.Inner inner = new Outer.Inner(); inner.sayHello(); // 方式2,编写一个方法,返回静态内部类的实例。 Outer.Inner inner1 = new Outer().getInnerInstance("java"); inner1.sayHello(); // 方式2的补充,可以在外部类中写静态方法,返回静态内部类的实例,没有本质区别 Outer.Inner inner2 = Outer.getInnerInstance_("HSP"); inner2.sayHello(); } } class Outer { private int n1 = 10; private static int n2 = 20; // 静态内部类 public static class Inner { private String name; private static int count = 0; private static int n2 = 30; // 静态内部类可以有构造器 Inner(String name) { this.name = name; } Inner() { } // 静态类里可以有普通方法 public void sayHello() { // 展示静态内部类访问外部类的方式。 // System.out.println(n1); 不能直接访问外部类非静态成员变量 System.out.println(new Outer().n1); // 但是可以通过创建外部类实例来访问外部类非静态变量 System.out.println(Outer.n2); // 可以直接访问外部类静态变量 System.out.println(n2); // 直接访问遵循就近原则 System.out.println("Hello, I'm " + this.name); // 也可以访问本类非静态变量 System.out.println("Total count: " + count); // 也可以访问本类静态变量 } } // 接下来展示外部类如何访问静态内部类 public void accessInner() { Inner inner = new Inner("HSP"); // 创建静态内部类对象 System.out.println(inner.name); // 访问静态内部类成员变量 System.out.println(Inner.count); // 访问静态内部类静态成员变量 } public Inner getInnerInstance(String name) { return new Inner(name); // 创建静态内部类对象并返回给调用方 } public static Inner getInnerInstance_(String name) { return new Inner(name); // 创建静态内部类对象并返回给调用方 } } 综合练习 练习1 当前代码会不会报错?为什么? public class Test { class Inner { public int a = 5; } public static void main(String[] args) { Inner r = new Inner(); } } 答案: 会报错,因为成员内部类在创建时依赖外部类的实例而存在,需要一个外部类作为容器,传统初始化方法为 “外部类实例.new 成员内部类名” main方法是静态的,静态方法中没有this关键字,因而报错,下面这样做就可以 public class Outer { public class Inner { } // 实例方法(非静态方法) public void show() { Inner inner = new Inner(); // ✅ 可以! // 等价于:this.new Inner(); // 因为实例方法中,this 指向当前 Outer 对象 } } 练习2 下面这段代码会输出什么? public class Test { public Test() { Inner s1 = new Inner(); s1.a = 10; Inner s2 = new Inner(); System.out.println(s2.a); } class Inner { public int a = 5; } public static void main(String[] args) { Test t = new Test(); Inner r = t.new Inner(); System.out.println(r.a); } } 答案: 5 5 分析: Test构造器里初始化的 S1 和 S2 分别是两个不同的成员内部类实例,而 main 方法里初始化的 r 也是一个不同的成员内部类实例。三个方法中的 a 是独立的 1 个帖子 - 1 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-06-08 14:59:06+08:00 · tech

其它的笔记统计在了 JAVA学习记录总贴 中,欢迎大家点评 接口 一个简单例子 public class Interface01 { public static void main(String[] args) { Camera camera = new Camera(); Phone phone = new Phone(); Computer computer = new Computer(); computer.work(camera); computer.work(phone); } } public interface UsbInterface { public void start(); ​ public void stop(); } public class Phone implements UsbInterface { @Override public void start() { System.out.println("手机开始工作..."); } ​ @Override public void stop() { System.out.println("手机停止工作..."); } } public class Camera implements UsbInterface { @Override public void start() { System.out.println("相机开始工作..."); } ​ @Override public void stop() { System.out.println("相机停止工作..."); } } public class Computer { public void work(UsbInterface usbInterface){ usbInterface.start(); usbInterface.stop(); } } 基础语法 interface 接口名{ //属性 //方法 } class 类名 implements 接口名{ 自己属性; 自己方法; 必须实现的抽象方法; } ps: jdk7.0之前,接口内的所有方法都是抽象方法,即没有方法体。 jdk8.0后,接口可以有静态方法、普通方法,也就是说接口中可以有方法的具体实现,但写方法需要使用default关键字 public interface AInterface { public int n1 = 10; public void hi(); ​ // 普通方法要写default关键字 public default void ok(){ System.out.println("ok()方法被调用"); } ​ public static void cry(){ System.out.println("cry()方法被调用"); } } 接口应用场景 我们思考一个场景:假设一位产品经理和三位程序员一起工作,需要编写三个类,分别实现对 MySQL、Oracle、DB2 数据库的连接与关闭操作。 如果不使用接口,三位程序员很可能会按照各自的标准来写,结果开发出三个方法命名各异、实现方式也不同的类。产品经理拿到这些类后,甚至可能发现连方法名都无法统一,自然也难以进行统一调用。 但如果产品经理提前设计好接口,在接口中定义好需要被实现的方法,三位程序员只需按照这个接口去开发即可。这样最终得到的类不仅方法命名统一,而且因为它们都实现了同一个接口,产品经理还可以利用多态特性,轻松实现统一调用。 因此接口的好处是 规范统一 多台调用 public class Interface2 { public static void main(String[] args) { Interface2.useDatabase(new MySql()); Interface2.useDatabase(new Oracle()); Interface2.useDatabase(new DB2()); } ​ public static void useDatabase(DateBase dateBase){ dateBase.connect(); dateBase.close(); } } ​ interface DateBase { public void connect(); ​ public void close(); } ​ class MySql implements DateBase { ​ @Override public void connect() { System.out.println("连接MySql数据库"); } ​ @Override public void close() { System.out.println("关闭MySql数据库"); } } ​ class Oracle implements DateBase { ​ @Override public void connect() { System.out.println("连接Oracle数据库"); } ​ @Override public void close() { System.out.println("关闭Oracle数据库"); } } ​ class DB2 implements DateBase { @Override public void connect() { System.out.println("连接DB2数据库"); } ​ @Override public void close() { System.out.println("关闭DB2数据库"); } } 接口使用细节 接口本身是不能实例化的。 接口中写抽象方法可以省略abstract关键字,接口中的所有方法默认是public 一个普通类实现接口,就必须将该接口的所有方法都实现 抽象类实现接口,可以不用实现接口的方法 一个类可以同时实现多个接口 接口中的属性默认且只能是 public static final 的,比如 int a = 1; 其实就是 public static final int a = 1; (你可以修改一下值,就能证明是 fianl 的;写 private int a = 1; 会报错,也能证明它是public的) 接口中属性的访问方式:接口名.属性名(因为本质是静态的嘛) 一个接口不能继承其他的类,但是可以继承别的多个接口,比如 interface A extends B, C{} 接口之间的关系是继承,接口和类之间的关系是实现 接口的修饰符合类一样,只能是默认或者public 小练习 interface A{ int a = 23; } ​ // 实现接口的类 class B implements A{ } ​ // main方法所在的测试类(补充完整可运行结构) public class Test { public static void main(String[] args) { B b = new B(); System.out.println(b.a); System.out.println(A.a); System.out.println(B.a); } } 请判断上述代码语法是否可以通过 答案如下 全都可以通过。 int a=23相当于public static final int a=23,没问题 A里面没有抽象方法,所以B不需要实现 三种a的调用方法,由于a本身是静态的,因此无论是用A(接口)B(实现接口的类)b(实现接口的类的对象),都可以完成调用,不过第三种形式不推荐。 接口 VS 继承 java中的实现机制,可以看作是对继承机制的一种补充。 接口和继承解决的问题不同 继承价值在于:解决代码的复用性和可维护性 接口价值在于:设计好各种规范方法,让其他类去实现 接口比继承更加灵活 继承是 is-a的关系 接口是 can do的关系 接口在一定程度上实现了代码解耦【依赖于接口规范性+动态绑定机制】 // 继承:is-a 关系 class Animal {} class Dog extends Animal {} // Dog is an Animal ​ // 接口:can do 关系 interface Swimmable { void swim(); } interface Flyable { void fly(); } ​ // 一个类可以同时具备多种能力 class Duck extends Animal implements Swimmable, Flyable { @Override public void swim() { System.out.println("鸭子游泳"); } @Override public void fly() { System.out.println("鸭子飞"); } } 接口的多态特性 是的,接口也可以实现多态,代码示例如下: public class Interface2 { public static void main(String[] args) { useDatabase(new MySql()); useDatabase(new Oracle()); useDatabase(new DB2()); } static void useDatabase(DateBase dateBase){ dateBase.connect(); dateBase.close(); } } ​ interface DateBase { public void connect(); ​ public void close(); } ​ class MySql implements DateBase { @Override public void connect() { System.out.println("连接MySql数据库"); } ​ @Override public void close() { System.out.println("关闭MySql数据库"); } } ​ class Oracle implements DateBase { ​ @Override public void connect() { System.out.println("连接Oracle数据库"); } ​ @Override public void close() { System.out.println("关闭Oracle数据库"); } } ​ class DB2 implements DateBase { @Override public void connect() { System.out.println("连接DB2数据库"); } ​ @Override public void close() { System.out.println("关闭DB2数据库"); } } 可以看到 useDatabase(DateBase dateBase) 接收一个DataBase接口类型的参数,但是实际上可以传入实现该接口的类的实例,并且根据每个类不同的实现来调用 此外,还可以这么做 DateBase db = new DB2(); //接口的向上转型 DB2 db1 = (DB2)db; //接口的向下转型 当然也可以写接口数组,来实现多态特性 DateBase[] databases = new DateBase[3]; databases[0] = new MySql(); databases[1] = new Oracle(); databases[2] = new DB2(); for (DateBase database : databases) { database.connect(); database.close(); } 此外,接口的多态特性也是可以传递的,如下代码 public class Interface3 { public static void main(String[] args) { IH ih = new T(); IG ig = new T(); } } ​ interface IG{} interface IH extends IG{} class T implements IH{} 小练习2 下面这段代码是否有错,如果有该如何修改呢? interface A{ int x = 0; } class B{ int x = 1; } class C extends B implements A { public void pX(){ System.out.println(x); } public static void main(String[] args) { new C().pX(); } } 答案: 有错,类C同时继承了B的x和接口A的x,无法确定x是哪个,修改方法是 if你想访问接口的x then A.x if你想访问父类B的x then super.x 2 个帖子 - 2 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-10 03:37:51+08:00 · tech

首先感谢两位大佬分享的方法和制作的脚本: 完全准确查询你的GPT订阅周限的方法 开发调优 目前认为该方法可行,当然也有可能被推翻 https://chatgpt.com/codex/cloud/settings/analytics#usage 的 https://chatgpt.com/backend-api/wham/analytics/daily-workspace-usage-counts?start_date=2026-04-09&end_date=2026-05-08&g… 完全准确查询你的GPT订阅周限的方法【油猴脚本】 开发调优 首先感谢 完全准确查询你的GPT订阅周限的方法 提供的思路和 js 脚本。 基于大佬的内容优化为了油猴脚本,看起来更方便。 附个人 pro 20x 结果示例图: [image] 打开 https://chatgpt.com/codex/cloud/settings/analytics#usage 页面使用 // ==UserScript== // @name Code… 亲测确实很不错,唯一可能有问题的地方在于每周重置的时间不是当天用量统计开始的时间,所以可能每个人的结果都有细微偏差。 特此想做一个持续更新的帖子,让大家都能了解 Codex 各套餐最新的限额。 我先来抛砖引玉: 美区正价 Pro 5x(当前为限时10x期间),周限额 $ 1447.55 4 个帖子 - 2 位参与者 阅读完整话题

linux.do · 2026-05-03 22:43:10+08:00 · tech

看看你们干的好事(无恶意) 以后还是在这里发吧… ClawEmail邀请码分享 福利羊毛 (已更新)邀请码分享: CLAW15FAB58391C0(已使用) CLAW5750DF7DE13E(已使用) CLAW892440AD70B8(已使用) CLAW46134EE50476(已使用) CLAW990756A828D2(已使用) CLAWE5624636F7B5(已使用) CLAWBFE062D57DB2 CLAW157CDF06654C(已使用) CLAW9252… https://linux.do/t/topic/2105141 (一级) 我也来几个ClawEmail邀请码 分享一波ClawMail的邀请码 分享ClawEmail几个激活码 我也放几个 CLAW82098ADB534E CLAW483AEB69CA55 CLAW68918F0C8439 5 个帖子 - 5 位参与者 阅读完整话题