java基础
1.接口
public class Interface1 {
public static void main(String[] args) {
/*
TODO 接口:
1.为什么需要接口?
对于某一些类来说,需要对其添加一些额外的拓展功能,但是这些功能在具体的类中具有不同的实现方式
对于个人电脑来说,为了增加其功能,提供了一些接口 类似于 use接口 雷电3接口等等
通过这样的一些接口,那么可以给电脑添加额外的功能:通过use连接鼠标,硬盘,或者添加一些显示设备
对于定义的Java类来说也是为了其能增加一些行为
2.怎么使用接口?
接口用关键字interface表示
格式:interface 接口名 {}
接口本身并没有提供具体的行为方式,所以需要具体的类来实现
类实现接口用implements表示
格式:class 类名 implements 接口名 {}
注意:对于类要实现接口,那么要求实现其接口中的抽象方法,或者当前类是一个抽象类
3.接口和类的关系
接口只定义规范,标记了当前接口的 方法名称 传入的参数类型 以及返回值类型
类是需要实现具体接口提供规范的执行逻辑
4.当一个类需要继承父类和实现接口时,如何编写?
extends Cat implements Domestication {} 先继承后实现,否则会报错
5.接口是否可以多实现?
可以的,implements 接口1,接口2 没有钻石问题
6.接口是否存在实现对象
接口是抽象的,不能被实例化
7.当接口作为参数被使用时,那么可以将接口的实现类对象传入到当前方法中进行使用
为什么要使用接口作为参数类型?
当前接口的方法规范已经给出,但是没有具体实现,那么此时,可以对类中的方法
调用该接口中抽象的方法,等到某个实现类实现了该方法,那么就可以对当前类中方法进行使用
对于现实场景来说,一种方法的执行逻辑可能会有很多中,为了增加Java的拓展性以及容错性
降低耦合性上来说,接口是一个很好的选择
*/
System.out.println(new DomesticationCat().compute(2, 3));
// 具体的编程脑机接口
ProgrammingInterfaceType programmingInterfaceType = new ProgrammingInterfaceType();
// new DomesticationCat() 被神化后的猫对象 想要让其编程 要接入Java的脑机
new DomesticationCat().programming(programmingInterfaceType);
}
}
interface USB {
public void use3(String type);
}
class Agreement {
}
class Computer implements USB {
public void watchMovie() {
System.out.println("电脑可以看电影");
}
public void input() {
System.out.println("电脑可以使用自带的键盘触摸板来接受信息");
}
@Override
public void use3(String type) {
if (type.equals("鼠标")) {
System.out.println("开始调用鼠标的功能,可以进行输入设备的移动数据");
} else if (type.equals("键盘")) {
System.out.println("开始调用键盘的功能,可以进行输入设备的指令数据");
} else if (type.equals("硬盘")) {
System.out.println("开始调用硬盘的功能,可以进行读取数据");
} else {
System.out.println("设备识别错误...无法调用");
}
}
}
class Equipment implements USB {
@Override
public void use3(String type) {
if (type.equals("天线")) {
System.out.println("可以接收雷达信号");
} else {
System.out.println("识别错误,无法调用..");
}
}
}
interface Domestication {
public String compute(int x, int y);
}
interface Apotheosis{
public void programming(InterfaceType interfaceType);
}
class Cat {
public void eat() {
System.out.println("🐱会吃猫粮");
}
}
class DomesticationCat extends Cat implements Domestication,Apotheosis {
@Override
public String compute(int x, int y) {
String res = "";
for (int i = 0; i < x + y; i++) {
res += "喵";
}
return res;
}
@Override
public void programming(InterfaceType interfaceType) {
// if (interfaceType.equals("编程接口")){
// System.out.println("🐱可以完成编程任务");
// }else {
// System.out.println("猫被神话,可以完成很多任务...");
// }
boolean res = interfaceType.programmingType("Java");
if (res){
System.out.println("🐱可以完成Java编程任务");
}else {
System.out.println("接口连接失败,需要再次尝试...");
}
}
}
interface InterfaceType{
public boolean programmingType(String language);
}
/*
可以编程的脑机接口
可以让 实现 Apotheosis 神化接口的类 进行调用其programming方法
*/
class ProgrammingInterfaceType implements InterfaceType{
@Override
public boolean programmingType(String language) {
if (language.equals("Java")){
System.out.println("看来您想使用Java这项神迹,现在赋予给你...");
System.out.println("...");
System.out.println("你会了");
return true;
}else {
System.out.println("现在该脑机接口只会Java,其他的请使用其他脑机接口");
System.out.println("...");
return false;
}
}
}
2.接口与接口、接口与抽象类之间的关系
public class Interface2 {
public static void main(String[] args) {
/*
TODO 接口
1.接口和接口之间的关系
接口之间如果要继承需要使用extend来继承,如果要使用类实现接口需要使用 implement
同时接口和接口之间可以进行多继承或多层继承
2.接口和抽象类之间的关系
抽象类可以通过implement实现接口,但是接口中的抽象方法,可以选择实现,也可以不实现
对于抽象类如果要调用,需要使用其子实现类的对象来进行调用
*/
new C().function1("A");
new F().function2("B");
B b = new F(); // 接口使用多态
b.function2("B");
System.out.println(b.VALUE);
// b.value = 20; // TODO 对于接口中定义的变量称为常量 默认使用 final static 进行修饰
}
}
interface A {
public void function1(String str) ;
}
interface D {
public void function1(String str) ;
}
interface B extends A,D {
//静态常量VALUE,可以利用B的子实现类的对象.VALUE实现调用
final static int VALUE = 10;
public void function2(String str) ;
}
class C implements B {
@Override
public void function1(String str) {
System.out.println("C类实现了A接口中方法");
}
@Override
public void function2(String str) {
System.out.println("C类实现了B接口中的方法");
}
}
abstract class E implements B {
@Override
public void function2(String str) {
System.out.println("抽象类E实现了B接口中的方法");
}
}
class F extends E{
// static int VALUE = 30;
@Override
public void function1(String str) {
System.out.println("F实现了A中的抽象方法...");
}
}
class Person{
}
abstract class Teacher extends Person{
}
3.包、权限修饰符
/*
TODO 包:
包的概念:
包在Java中就是文件夹
由多个包组成的 包名.包名 方式称为包路径
如果存在由 包名.包名.类 该方式称为类路径 => com.shujia.day06.Demo04Package
快捷方式 选择类名 右键 => copy reference
包是在源目录下 依据层级生成
作用:对类进行分类管理
TODO
package com.shujia.day06; => 指定当前类所属的包路径 =>
在编译器中可以根据该标识信息将编译的结果文件存放到指定路径
package语句必须是程序的第一条可执行的代码
package语句在一个java文件中只能有一个
如果没有package,默认表示无包名
TODO 不同包中的类的使用
1.对于不同包中类,相互调用,那么需要使用 import 关键字,指定其类路径
2.如果使用的类是当前包下的,那么不需要使用import导入,其他都需要导入
alter + enter 键选择需要导入的类
3. 使用 * 可以表示当前包下所有类
4. import 语句只能在 package下 class上进行定义
*/
/*
TODO Java中权限修饰符
protected 受保护的权限,在不同包中的其他类不能访问
默认 不写权限 在不同包下都不能访问
private 私有权限 只能在当前类中进行使用
*/
// 构造方法私有时,该如何调用其构造方法的例子:
class Demo06Util {
public static void main(String[] args) {
// new Util(); // 构造方法私有
//注意实现方式
Util util1 = Util.getObject("参数1");
Util util2 = Util.getObject("参数2");
/*
com.shujia.day06.Util@4554617c
com.shujia.day06.Util@4554617c
表示同一个对象
该写法可以保证其他程序员在使用该代码时,只能在全局创建唯一一个对象
*/
System.out.println(util2);
System.out.println(util1);
}
}
class Util {
String parameter;
static Util utilObject; // 所有对象所共有,可以被对象或类进行访问
// 构造方法私有
private Util(String parameter) {
}
// 对于一些工具类,可以提供静态方法 直接通过类名.方法进行调用 =>
static {
createObject("初始化参数");
}
//传递参数类型为Util类的实例化对象
private static void createObject(String parameter){
utilObject = new Util(parameter);
}
public static Util getObject(String parameter){
utilObject.parameter = parameter;
return utilObject;
}
}
4. 内部类
package com.shujia.day06;
public class Demo07InnerClass {
static class InnerClass3 {
public void innerFunction() {
System.out.println("这是静态内部类中的一个成员方法");
}
}
public static void main(String[] args) {
/*
TODO 内部类
1. 当类定义在另一个类中时,该类称为 成员内部类
需求:创建成员内部类对象并调用其方法
逻辑:
成员内部类 是成员,属于外部类对象的 所以需要先构建外部类的对象
通过调用对象的 new 再创建 成员内部类 的对象
例如:new OuterClass().new InnerClass1();
*/
//创建另一个类中的成员内部类对象并调用其方法
OuterClass.InnerClass1 innerClass1 = new OuterClass().new InnerClass1();
innerClass1.innerFunction();
// 调用另外一个类中的静态内部类
OuterClass.InnerClass2 innerClass2 = new OuterClass.InnerClass2();
// 调用当前类中的静态内部类
InnerClass3 innerClass3 = new InnerClass3();
// 通过方法调用其局部内部类,注意其生命周期
OuterClass.useInnerClassFun();
// 通过接口构建了一个匿名的内部类 进行实现
OuterInterface outerInterface = new OuterInterface() {
@Override
public void innerFunction() {
System.out.println("这是接口的匿名内部类所实现的方法");
}
};
// TODO: 该方式不是接口的实例调用,而是匿名内部类的对象进行调用
outerInterface.innerFunction();
// TODO 对抽象类构建匿名对象
new OuterAbstractClass() {
@Override
public void innerFunction() {
System.out.println("这是抽象类的匿名内部类所实现的方法");
}
}.innerFunction();
}
/*
为了使用方便,将多个class定义在一个.java文件中,相当于在包中定义了一个类
但是一个.java文件只能有一个 public 修饰的class类 OuterClass 不是内部类
*/
class OuterClass {
/*
TODO 成员内部类 => 属于外部类对象的
*/
class InnerClass1 {
public void innerFunction() {
System.out.println("这是成员内部类中的一个成员方法");
}
}
/*
TODO 静态内部类 => 属于外部类
*/
static class InnerClass2 {
public void innerFunction() {
System.out.println("这是静态内部类中的一个成员方法");
}
}
public static void useInnerClassFun() {
int i = 10; // 局部变量
/*
TODO 局部内部类
会随着方法的调用而创建,随着方法的结束而消失
*/
class InnerClass4 {
public void innerFunction() {
System.out.println("这是局部内部类中的一个成员方法");
}
}
new InnerClass4().innerFunction();
}
}
/*
TODO 匿名内部类
需求:当存在接口,对其中的抽象方法,仅使用一次 或者需要构建接口的对象时,可以不定义具体的类
使用匿名内部类方式进行操作
*/
interface OuterInterface{
public void innerFunction() ;
}
abstract class OuterAbstractClass{
// TODO 对于抽象类 抽象方法需要添加 abstract 修饰
public abstract void innerFunction() ;
}
5. Object类
import java.util.Scanner;
public class ObjectClass {
public static void main(String[] args) {
/*
TODO Object类:
Object 是所有类的顶级父类 默认在运行时对其进行设置
对于Java中的类,都可以获取到顶级父类中继承的方法
*/
// 默认有无参构造
Object object1 = new Object();
Obj obj1 = new Obj();
/*
TODO 方法:
clone():浅拷贝
如果两个Person对象的name的地址值相同, 说明两个对象的name都指向同一个String对象, 也就是浅拷贝,
而如果两个对象的name的地址值不同, 那么就说明指向不同的String对象, 也就是在拷贝Person对象的时候,
同时拷贝了name引用的String对象, 也就是深拷贝。
equals => 判断两个对象是否相等
equals 默认底层使用 == 对两个对象地址进行判断,如果地址相同,那么结果为true
hashCode() => 返回对象的Hash值,该函数是一个映射函数 传入一个值,肯定有一个唯一对应的随机的值
返回对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。
*/
// public boolean equals(Object obj)
Object object2 = new Object();
Object object3 = object1;
System.out.println(object1.equals(object3)); // true
System.out.println(object1.equals(object2)); // false
Obj obj2 = new Obj();
Obj obj3 = obj1;
System.out.println(obj1.equals(obj3)); // true
System.out.println(obj1.equals(obj2)); // false
String str = "1";
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串");
String inputStr = scanner.next();
if (str == inputStr){
System.out.println("通过 == 判断 输入的1和定义的1相等");
}else if (str.equals(inputStr)){ // TODO 对于字符串的equals方法 对其进行了重写 不是Object中的逻辑
System.out.println("通过 equals 判断 输入的1和定义的1相等");
}else {
System.out.println("不相等");
}
/*
补充: instanceof => 用于判断某个对象是否为类的实例
*/
System.out.println(obj3 instanceof Obj); // true => 如果是继承关系呢?
Per per1 = new Per("001");
Per per2 = new Per("001");
// 虽然为两个内存地址,但是表示的内容是一样的
System.out.println("比较结果:"+per1.equals(per2));
Obj obj = new Obj();
System.out.println("比较结果:"+per1.equals(obj));
System.out.println("hash值:"+obj.hashCode()); // 692404036
}
}
class Obj{
}
class Per{
String id;
public Per(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
// 此时需要对两个人进行判断,判断依据是ID 是否相同
// Object 是所有类的父类 => 通过强制类型转换 将其转换成 Per
if (obj instanceof Per){
Per otherPer = (Per) obj;
return this.id.equals(otherPer.id);
}else {
return false;
}
}
}