面向对象
这篇文章介绍了Java中的类、接口、注解、枚举和多态。
类 (Class)
- Java类与C++类似,可以封装属性和方法。Java是纯面向对象语言,所有逻辑都通过类完成。
- 成员类型:包括非静态成员(隶属于对象)和静态成员(隶属于类)。
- 内部类:包括非静态内部类(隶属于对象)和静态内部类(隶属于类)。
- 局部类:定义在方法内部,只能在方法内使用,不能有静态成员,可以只读访问外部方法的final变量。
- 成员权限:private(本类)、默认(本类及同包)、protected(本类、同包及子类)、public(所有位置)。
继承 (Inheritance)
- Java类只支持单继承,不支持多继承。
- 所有Java类都直接或间接继承自
Object类,该类提供了getClass()、toString()、equals()、hashCode()等共性方法。
接口 (Interface)
- Java接口是一种特殊的抽象类,可以包含抽象非静态方法、静态常量、静态内部类、默认方法和静态方法。
- 类可以通过
implements关键字实现接口,并需要实现接口中的抽象方法。 - 接口支持继承,一个接口可以继承另一个接口。
- 函数式接口:只有一个方法的接口,常用于Lambda表达式。
注解 (Annotation)
- 注解本质上是一个接口,继承自
java.lang.annotation.Annotation。 - 注解的返回值类型只能是基本数据类型、String、枚举、注解或它们的数组。
- 注解的方法被解释为属性,使用时需要按声明顺序赋值,或在只有一个名为
value属性时省略属性名。 - 内置注解包括文档注解(
@author、@version)、@Override、@Deprecated、@SuppressWarnings等。
枚举 (Emuration)
- (内容未详细展开,但提到了该标题)
多态 (Polymorphism)
- 函数重载:与C++一致。
- 函数重写:Java的类方法相当于C++的虚函数。
abstract修饰的方法相当于纯虚函数。 - 对象转型:使用
instanceof进行判断。 - 语法糖:可以通过匿名内部类进行类继承和接口实现。当访问外部变量时,变量需为
final。 - Lambda表达式:用于实现函数式接口,可简化代码,支持捕获局部变量,并提供参数类型、括号、代码体的大括号、分号和
return的省略规则。 - 方法引用:当函数式接口的方法签名与现有方法匹配时,可以使用方法引用,包括非静态方法引用、静态方法引用和构造方法引用。
泛型 (Generics)
- 泛型可以用于类或接口的定义,用于指定数据类型,创建对象时可确定泛型类型,缺省默认为
Object。 - Java泛型只支持引用类型,不支持基本数据类型。
- 泛型通配符:使用
?匹配类型。?:匹配任何类型。? extends 类名:匹配指定类及其子类。? super 类名:匹配指定类及其父类。
- 使用泛型通配符会限制对返回值的操作,通常只能调用
Object类的方法,或通过instanceof进行向下转型。
Class
Java类可以和C++一样,可以封装属性和方法,Java是纯面向对象语言,一切逻辑交由类完成。
public class MyClass {
/*非静态成员变量: 隶属对象,必须通过具体对象调用。
*/
private Integer noneStaticVariable;
/*非静态成员方法:隶属对象,必须通过具体对象调用。
- 构造方法中,super调用父类构造方法必须在第一行
*/
private void noneStaticFunction(){return;}
/*非静态内部类:
- 隶属对象,其实例必须通过具体对象进行创建。
- 非静态内部类只能拥有非静态成员
- 非静态内部类的非静态成员方法可以访问外部类对象的所有非静态成员(重名时需要通过`外部类.this.变量名`指定)
*/
private class NoneStaticInnerClass {}
/*静态成员变量:隶属类,可通过类或类对象调用。*/
public static Integer staticVariable;
/*静态成员方法:隶属类,可通过类或类对象调用。*/
public static void staticFunction(String[] args) {return;}
/*静态内部类:隶属类,其实例可通过类或类对象创建。*/
public static class InnerClass{}
/* 定义在方法中的类叫做局部类, 它只能在方法内使用.
- 不能限定权限
- 不能拥有静态成员
- 局部类内的方法可以只读访问外部方法中的final常量或只进行过一次赋值的变量
*/
public static void function(){
final Integer finalVariable = 1;
class InnerClass{
public void function(){
System.out.println(finalVariable);
//finalVariable = 2; //sytnx ERROR.
}
}
}
}
成员权限类型
- private: 只有本类可以使用
- <Not Specified>: 只有本类以及同一包下的类可以访问, 这是java类的默认权限
- protected: 只有本类以及同一包下的类, 在加上继承类可以使用
- public: 所有位置可以使用
Inheritance
java类只支持单继承, 不支持多继承, java类继承不分继承模式,
class myClass extend BaseClass implement Interface{}
java中所有的类都直接或间接继承自Object类, 它封装了所有类的共性方法.
/*返回此对象的类的Class对象, 也可以通过 className.class的方法获取*/
Class getClass();
/*返回对象的类所在的包路径以及对象的内存地址*/
string toString();
/*单纯比较两个引用是否相等(比较物理内存地址), 它和\=\=号功能是相同的*/
bool equals(Object o);
/*native是系统调用方法, hashCode也叫哈希摘要, 或内容摘要. 不同的内容哈希值一定不同, 相同内容的哈希值一般不同, 当哈希值相同时还需要比对内容.*/
native int hashCode();
Interface
Java接口是一种特殊的抽象类,它的基本组成如下:
public interface MyInterface {
/**抽象非静态方法
- 默认包含abstract、public特性,关键字可忽略。
*/
abstract public void noneStaticFunction();
/**静态常量
- 默认包含public、static、final特性,关键字可忽略
*/
public static final Integer staticVariable = 1;
/**静态内部类
*/
public static class InnerClass{}
/** 新JDK支持默认非静态方法,用于解决兼容性问题
- 默认包含public特性,关键字可忽略。
*/
default public void noneStaticFunction2() {return;}
/** 新JDK支持静态方法,但需要通过接口名调用
- 默认包含public特性,关键字可忽略。
*/
public static void staticFunction(){return;}
private static void staticFunction2(){return;}
}
接口需要一个类实现,类中主要实现接口中的抽象非静态方法,按需重写其他方法。
public class MyObject implements MyInterface {
@Override
public void noneStaticFunction() {retuen;}
}
Inheritance
interface myInterface extend BaseInterface { /*接口定义*/ }
Functional
函数式接口是接口中只有一个方法的接口,java.util.function包下定义了很多实用的函数式接口。
Annotation
- 注解其实是一个接口, 它继承了
java.lang.annotation.Annotation这个接口 - 返回值类型只能是基本数据类型、String、枚举、注解、以上类型的数组
- 注解的方法被解释成属性, 返回值即它的类型. 在使用注解时需要按声明顺序赋值(仅有一个属性且其名称为value时传值可以不用输入属性名)
- 注解在加载到内存中是编译器会实现注解并产生一个子类对象, 通过该对象调用注解方法可以获取注解配置的属性值
@Target(value={ElemType.type,...}) //描述注解作用位置,type可以作用于类上
@Retention(Retention.RUNTIME) //描述被保留的阶段, RUNTIME保留到运行期
@Documented //注解是否被抽取到文档
@Inherited //使用该注解的类被继承时子类是否同样使用该注解
public @interface MyAnnotation{
int baseTyep();
String string() default "张三"
MyAnnotation annotation();
int[] arr();
}
//
@MyAnnotation(baseTyep=1,string="张三", annotation=@MyAnnotation, arr={1,2,3})
/*文档注解/*
@author
@version
/*jdk内置注解*/
@Override
/*过期标注*/
@Deprecated
/*压制警告*/
@SuppressWarnings("all")
Emuration
Polymorphism
函数重载 和C++一致
函数重写 Java的类方法相当于C++的虚函数, abstract修饰的类方法时相当于C++的纯虚函数, 拥有抽象方法的类是抽象类 打印函数其实接收的是Obeject类, 父类指针指向子类对象, 这里使用了多态, 然后调用了父类的toString方法
对象转型 instanceof
语法糖 可以使用Java提供的匿名内部类进行类继承与接口实现,当匿名内部类需要访问外部变量时,这个变量应该被final修饰
MyClass myObject = new MyClass(){ /*子类定义*/ }
MyInterface myObject = new MyInterface(){ /*实现类定义*/ }
若接口是函数式接口,那该接口可以通过Lambda表达式实现并实例化。
MyInterface myObject = (arg1, arg2, ...) ->{/*函数式接口中方法的定义*/}
- Lambda能捕获局部对象的引用
- 若接口的参数的类型是固定的或泛型可以根据形参推导, 则可省略参数类型
- 若接口只有一个参数则可以省略()
- 若代码体只有一行代码则可以省略{} 、分号以及return, 返回值就是这行代码的返回值
当函数式接口的方法返回值和参数列表和已知的方法相同时, 可以通过方法引用
- 非静态方法引用
类对象::非静态方法,注意类对象必须已经存在, 注意类中this和super也是可以用的 - 静态方法引用
类::静态方法,注意类必须已经存在 - 构造方法引用
类::new基本数据类型[]::new自动匹配构造器
Generics
permission <T> class/interface ClassName{
/*类或接口内容*/
}
- 创建对象的时候可以确定泛型的类型, 若缺省则默认是Object类型
- java的泛型只支持引用类型, 不支持基本数据类型
- 泛型通配符: 当类或接口作为参数时, 泛型可以使用?匹配类型
void function(className<?> p){方法体}
void function(className<? extends 类名> p){方法体} 匹配指定类的子类
void function(className<? super 类名> p){方法体} 匹配指定类的父类
使用泛型通配符的后果是, 这个对象返回的任何泛型量仍然不确定的, 可以确定的是它一定是继承自Object类 所以根据多态的特性可以使用泛型量中Object的方法. 也可以使用instanceof判断从而支持向下转型使用更多方法