目录
1.抽象类与抽象方法
注意:
抽象类不能实例化
抽线类中不一定有抽i像方法,有抽象方法的类一定是抽象类
可以有构造方法
抽象类的子类要么重写抽象类中的所有抽象方法,要么是抽象类
抽象类的作用:
抽取共性时,无法确定方法体,就把方法定义为抽象的。
强制让子类按照某种格式重写。
抽象方法所在的类,必须是抽象类
抽象类和抽象方法的格式?
public abstract 返回值类型 方法名 (参数列表);
public abstract class 类名{}
抽象类在多态方面的继承:
// 抽象类和抽象方法需要被 abstract 关键字修饰
abstract class Shape {
// 抽象类中的方法一般要求都是抽象方法,抽象方法没有方法体
abstract void draw();
}
// 当一个普通类继承一个抽象类后,这个普通类必须重写抽象类中的方法
class Cycle extends Shape {
@Override
void draw() { // 重写抽象类中的draw方法
System.out.println("画一个圆圈");
}
}
public class Test4 {
public static void main(String[] args) {
//Shape shape = new Shape(); 抽象类虽然不能直接实例化
// 但可以把一个普通类对象传给一个抽象类的引用呀,即父类引用指向子类对象
Shape shape = new Cycle(); // 这称作:向上转型
/*Cycle cycle = new Cycle();
Shape shape = cycle // 这是向上转型的另一种写法
*/
shape.draw(); // 通过父类引用调用被子类重写的方法
}
}
2.接口
接口:就是一种规则
例:兔子不会游泳,而青蛙和狗类会,则不能放在父类里,则需要创建一个具有游泳功能的接口。
接口设计规则:
- 抽取派生类的共同属性和行为抽到超类中,
- 抽象类:如果子类方法都一样设计为普通方法,如果子类的行为不是有一致的就写成抽象方法
- 接口:抽取部分子类相同行为,抽取到接口中——多继承,多实现,接口是对单继承的扩展
接口的定义与使用:
//接口定义的关键字interface
//接口都需要有实现类
public interface userService {
//接口中的所有定义都是抽象的 public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
public interface timeService {
void timer();
}
//类可以实现接口 implements
//实现了接口的类,就需要重写接口中的方法
//利用接口实现多继承
public class userServiceImpl implements userService,timeService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
接口的换代升级:
适用于添加接口新功能
3.内部类
内部类表示的事物是外部类的一部分,内部类单独出现没有任何意义。
内部类的访问特点:
1.内部类可以直接访问外部类的成员,包括私有
2.外部类要访问内部类的成员,必须创建对象
什么时候用到内部类?
例:需要录入车的信息,那么发动机的品牌,颜色,型号就可以当一个内部类
下图中Engine为内部类
内部类主要分为:静态内部类,非静态内部类。(static静态修饰)
注意:非静态内部类里不能有静态方法,静态成员变量,静态初始化块。
main获取内部类的对象:
1.Car.Engine r=new Car().new.Engine();直接创建(格式:外部类名.内部类名 对象名=外部类对象.内部类对象)
2.外部类编写方法,对外部类提供内部对象(private)
非静态外部类访问内部类
public class jtai {
private String prop="外部变量";
private class InClass {
private String prop = "内部变量";
public void print() {
String prop = "局部变量";
System.out.println("外面 " + jtai.this.prop);
System.out.println("内部 " + this.prop);
System.out.println("局部 " + prop);
}
}
public void test() {
InClass obj=new InClass();
obj.print();
}
public static void main(String[] args) {
new jtai().test();
}
}
非静态内部类访问外部类
// 外部类
class OuterClass {
private int outerField = 10;
// 内部类
class InnerClass {
void accessOuter() {
System.out.println("访问外部类的成员变量: outerField = " + outerField);
System.out.println("调用外部类的方法:");
outerMethod();
}
}
// 外部类的方法
void outerMethod() {
System.out.println("这是外部类的方法");
}
// 外部类的入口方法
public static void main(String[] args) {
// 创建外部类的对象
OuterClass outerObj = new OuterClass();
// 创建内部类的对象
OuterClass.InnerClass innerObj = outerObj.new InnerClass();
// 调用内部类访问外部类的方法
innerObj.accessOuter();
}
}
静态内部类:只能访问外部类中的静态变量和静态方法,如果想要访问非静态的想要创建对象。
静态内部类访问外部类:
// 外部类
class OuterClass {
private static int outerStaticField = 100;
private int outerField = 10;
// 静态内部类
static class StaticInnerClass {
void accessOuter() {
// 访问外部类的静态成员变量
System.out.println("访问外部类的静态成员变量: outerStaticField = " + OuterClass.outerStaticField);
// 若要访问外部类的非静态成员变量,需要通过外部类的对象访问
OuterClass outerObj = new OuterClass();
System.out.println("访问外部类的非静态成员变量: outerField = " + outerObj.outerField);
// 若要调用外部类的方法,也需要通过外部类的对象访问
outerObj.outerMethod();
}
}
// 外部类的方法
void outerMethod() {
System.out.println("这是外部类的方法");
}
// 外部类的入口方法
public static void main(String[] args) {
// 创建静态内部类的对象
StaticInnerClass innerObj = new StaticInnerClass();
// 调用内部类访问外部类的方法
innerObj.accessOuter();
}
}
外部类访问静态内部类
// 外部类
class OuterClass {
private static int outerStaticField = 100;
// 静态内部类
static class StaticInnerClass {
void innerMethod() {
System.out.println("这是静态内部类的方法");
}
}
// 外部类的方法
void outerMethod() {
System.out.println("这是外部类的方法");
// 在外部类的方法中创建静态内部类的对象并调用其方法
StaticInnerClass innerObj = new StaticInnerClass();
innerObj.innerMethod();
}
// 外部类的入口方法
public static void main(String[] args) {
// 在外部类的静态方法中创建静态内部类的对象并调用其方法
StaticInnerClass innerObj = new StaticInnerClass();
innerObj.innerMethod();
// 在外部类的静态方法中创建外部类的对象并调用其方法
OuterClass outerObj = new OuterClass();
outerObj.outerMethod();
}
}
有没有发现一个现象即静态与非静态的相互访问都需要用到关键字new,因为静态会开辟空间,呢哇也是。
注意:使用静态内部类比使用非静态内部类简单很多,只要把外部类当成静态内部类的包空间即可。
匿名内部类
匿名内部类是 Java 中灵活使用的一种语法结构,特别适合于需要实现简单接口或抽象类的场景,能够有效地减少代码量和提高代码的可读性。
简化代码结构: 匿名内部类可以在需要使用接口或抽象类的地方直接定义和创建对象,避免了编写独立类的繁琐过程,从而使代码更加简洁和紧凑。
事件处理: 在 GUI 编程中,匿名内部类常用于事件监听器的实现。通过匿名内部类,可以直接在事件发生时定义和处理事件的逻辑,而不必显式地定义一个专门的类。
延迟实例化: 如果一个类只需要使用一次,使用匿名内部类可以避免为这种用途专门编写一个完整的类,从而在逻辑上更加紧凑和高效。
接口实例化: 匿名内部类可以直接实现接口并创建接口的实例,比如在集合框架中的
Comparator
接口。访问外部变量: 匿名内部类可以访问其外部类的成员变量和局部变量(必须是隐式最终或实际上最终的变量),这使得它们在实现某些功能时更加灵活和强大。
尽管匿名内部类在某些情况下非常方便,但也有一些限制和注意事项:
- 不能有构造方法: 匿名内部类没有构造方法,因为它们没有类名。
- 不能定义静态成员或方法: 匿名内部类不能有静态成员或方法,因为它们没有类名。
- 不能是抽象类: 匿名内部类必须实现其继承的抽象类或接口的所有抽象方法。
Swim是类,Animal是类,第一个匿名内部类是实现关系,第二个是继承关系!在继承或者实现之后,想要重写所有的抽象方法。
(与上方代码变量不同)输出:重写之后的游泳方法
输出:狗吃骨头骨头骨头
4.BigInteger
1.获取随机大整数,范围【0~2的num次方-1】BigInteger(int num,Random t)
BigInteger r=new BigInteger(num,new Random());
2.获取一个指定的大整数,可以很大,大到long无法承载BigInteger(String s)
BigInteger r=new BigInteger(99999999999);
3.获取指定进制的大整数 BigInteger(String s,int num)
BigInteger r=new BigInteger(110,2); 二进制,110,输出6
5.BigDecima
1.通过传递double类型的小数来创建对象,都是不精确,存在误差。
2.通过传递字符串表示的小数来创建对象。String
3.通过静态方法获取对象。
通常使用后面两种,但是他们仍存在细微区别。
其他方法如下: