江苏省宝应城市建设有限公司网站,网站在建设中无法访问,阿里云虚拟主机装WordPress,璧山集团网站建设Java基础11——抽象类和接口
抽象类和抽象方法
区分普通方法和抽象方法
在Java 中#xff0c;当一个类被 abstract 关键字修饰的时候这个类称为抽象类。当一个类的方法被 abstract 关键字修饰的时候#xff0c;该方法称为抽象
方法。抽象方法必须定义在抽象类中。当一个方…Java基础11——抽象类和接口
抽象类和抽象方法
区分普通方法和抽象方法
在Java 中当一个类被 abstract 关键字修饰的时候这个类称为抽象类。当一个类的方法被 abstract 关键字修饰的时候该方法称为抽象
方法。抽象方法必须定义在抽象类中。当一个方法被定义为抽象方法后意味着该方法不会有具体的实现而是在抽象类的子类中通过方法重写进行实现。定义抽象方法的语法格式如下:
[访问修饰符]abstract 返回类型方法名([参数列表])
abstract 关键字表示该方法被定义为抽象方法。普通方法和抽象方法相比主要有下列两点区别:
抽象方法需要用修饰符 abstract 修饰普通方法不允许普通方法有方法体抽象方法没有方法体。
区分普通类和抽象类
在Java中当一个类被abstract关键字修饰时该类为抽象类。定义抽象类的方法如下 abstract class 类名{}abstract关键字表示该类被定义为抽象类。
普通类与抽象类相比主要有下列两点区别:
抽象类需要用修饰符 abstract 修饰普通类不允许普通类可以被实例化抽象类不可以被实例化。
public abstract class Person {//属性private String name 无名氏;private int age 100;private int weight 0;//构造方法public Person(String name){this.name name;}public void print(){System.out.println(我的名字是 this.name ,年龄是 this.age ,体重是this.weight .);}
}class Test{public static void main(String[] args) {//Pet pet new Pet(大黄);//错误示范因为抽象类不能实例化}
}定义一个抽象类
当一个类被定义为抽象类时它可以包含各种类型的成员包括属性、方法等其中方法又分为普通方法和抽象方法下面是抽象类结构的示例:
public abstract class 类名{修饰符 数据类型 变量名修饰符 abstract 返回值类型 方法名称(参数列表)修饰符 返回值类型 方法名称(参数列表){}
}提示:
abstract 修饰的抽象方法没有方法体private 关键字不能用来修饰抽象方法否则由于封装导致子类无法重写抽象方法抽象类不能被之间实例化但有构造方法子类如果不是抽象类则子类必须重写抽象类中的全部抽象方法abstract 修饰符不能和final修饰符一起使用
抽象类和具体类的比较
抽象类和具体类是面向对象编程中的两个重要概念 **抽象类: **抽象类是一种不能被实例化的类它只能被用作其他类的基类。它的目的是为了提供一种基于继承的模板强制要求子类实现它的抽象方法。抽象类中可能包含一些实现方法但是也可以只包含抽象方法。 抽象类的主要特点: 不能被实例化可以包含抽象方法和非抽象方法子类必须实现抽象方法抽象类可以包含构造函数。 具体类: 具体类是可以被实例化的类它可以直接使用也可以继承自其他类。具体类中必须要实现它的所有方法不能有未实现的方法。它可以包含属性、方法、构造函数等。 具体类的主要特点: 可以被实例化必须实现所有方法可以包含属性、方法、构造函数等。
两者的比较: 抽象类和具体类在定义上的差异抽象类是一种不能被实例化的类它只能被用作其他类的基类。具体类则是可以被实例化的类。 抽象类和具体类在实现上的差异抽象类可以包含抽象方法和非抽象方法子类必须实现抽象方法; 具体类必须实现它的所有方法不能有未实现的方法。 抽象类和具体类在使用上的差异抽象类通常用于定义一些基础的、通用的行为和属性而具体类则用于实现具体的业务逻辑和行为。 总的来说抽象类和具体类是两种不同类型的类它们的作用和使用场景也不同。 抽象类用于定义一些通用的行为和属性并强制子类实现抽象方法具体类则用于实现具体的业务逻辑和行为。
内部类
内部类是指讲一个类定义在另外一个类的内部称为内部类。
成员类可以解决类单继承问题
public class AbstractDemo {//外部类private static int a 0;private int b 3;public void a(){
// Abstr abstr new Abstr();new Abstr().test();Abstr.abc();}static class Abstr {private int aa 3;private static int bb2;public void test(){int a 5;System.out.println(aa);aa2;System.out.println(aa);System.out.println(bb);Abstr.bb4;System.out.println(bb);System.out.println(AbstractDemo.a);AbstractDemo.a5;System.out.println(AbstractDemo.a);System.out.println(a);}public static void abc(){System.out.println(a);Abstr.bb3;new Abstr().aa1;}}
class Abstra{//内部类private static int b 3;private int aa 2;public void test1(){int b 2;System.out.println(b);//当前类的对象AbstractDemo.this.b5;//外部类的对象System.out.println(AbstractDemo.this.b);}}public static void main(String[] args) {AbstractDemo.Abstr ab new AbstractDemo.Abstr();ab.test();Abstr.abc();AbstractDemo.Abstra abs new Abstractemo().new Abstra(); // abs.test1();}
} 内部类
在一个类中声明的类称为内部类. 内部类是一个嵌套类.
内部类包含以下几种:
成员类。在类的里面直接声明的类局部类。声明在一个块中, 当 main 方法调用结束就销毁匿名类。
匿名类
之前定义的类都是命名类也就是类都有明确的名称。匿名类是指没有明确名称的类。
public abstract class AbstractDemo2 {public static void test(){System.out.println(哈哈哈);}public abstract void play();
}public TestAbstract() {}
public static void main(String[] args) {AbstractDemo2 stu new AbstractDemo2() {Overridepublic void play() {System.out.println(发发发);}};stu.play();
}
}Notes:
static 成员类, 使用 类名. 调用. 使用 new 外部类.内部类();实例成员类 使用外部类的对象来调用. 使用 对象.new 内部类();成员类属于类的成员所以可以调用外部类的 private 成员在实例成员类中可以使用 外部类.this 表示外部类对象 (实例成员类是由外部类对象创建的)成员类中的 this 表示的是成员类外部类可以直接调用成员类的静态成员实例成员需要创建成员类的对象来调用外部类可以访问成员类的 private 成员类的成员 字段、方法、成员类/接口成员类内部类: 在类的里面声明的类. 可以被继承外部类的访问修饰符只能是 public / package-access成员类的访问修饰符可以是所有的访问修饰符可以使用 final static abstract 等修饰符修饰成员类
接口基本概念
约定好规范然后按照规范来做。接口就是定义规范。
描述规范的数据类型只定义规范不需要实现提供一种约定使实现接口的类在形式上保持一致。Java中规范可以用接口interface来表示
抽象类中可以有普通方法而接口中的方法默认都是抽象的也可以说接口是一个 ”特殊的 抽象类 “接口不能被实例化而且没有构造方法。
接口的格式
public interface 接口名{// 接口成员
}解析 定义接口使用interface修饰符 一个接口可以继承其它接口称为父接口且接口可以多继承它会继承父接口中声明的常量和抽象方法 成员列表中的成员变量声明[public][static][final] 数据类型 成员变量名 常量即接口中的成员变量默认都是public、static、final的因此public、static、final 可以省略 成员列表中的成员方法声明[public][abstract] 返回值类型 方法名称(参数列表)即接口中的方法默认都是public、abstract的因此public、abstract可以省略 接口中的变量只能是静态常量( static final ) , 所以可以省略 public static final 静态常量在定义时就要赋值且不可变。
接口的使用
与抽象类一样使用接口要通过子类子类通过implements关键字实现接口。
子类通过 implements 关键字实现接口实现接口就必须实现重写接口中的抽象方法
实现接口的语法格式如下
[修饰符] 类名 implements 接口名{ //实现方法// 普通方法// 属性} 解析
实现接口要用implements关键字一个类可以实现多个接口各接口之间用逗号分隔实现接口的类必须实现接口中定义的所有抽象方法即使类中不使用某个抽象方法也必须实现它通常用空方法体实现子类不需要的抽象方法如果抽象方法有返回值可返回默认值。接口的实现类允许包含普通方法在实现抽象方法时需要指定public权限否则会产生编译错误类和类之间叫做继承用extends类和接口之间叫做实现implement
多个接口实现
java 中继承是单继承,使用 extends 关键字
一个接口实现类可以实现多个接口使用 implements 多个接口之间用 , 隔开。
public class Computer implements USBInterface, ChargeInterface{ //定义一个实现类实现多个接口public void play() { // 普通方法System.out.println(play game); }Override
public void charge() { //重写抽象方法System.out.println(充电);
}Override
public void service() { //重写抽象方法System.out.println(USB接口); }
}一个类可以同时继承和实现接口 extends 要在 implements 之前
public class LenovoComputer extends Computer implements USBInterface, ChargeInterface{}接口与接口之间是继承关系使用 extends 关键字。多个接口使用 , 隔开
public interface USBC extends USBInterface,ChargeInterface{ } JDK8.0 接口新特性 default 和 static
**default**在 jdk8.0 中 default 关键字可用于在接口中修饰方法默认方法, default 修饰的方法可以有具体实现也只能在接口中出现。 default 修饰的方法可以被重写。
默认方法可以在不破坏已经在使用该接口的所有代码。默认方法有时也称为防御方法defender method或 虚拟扩展方法virtual extension method
**static**接口中还可以有 static 修饰的方法称为静态方法(类方法)。 static 方法必须直接使用 接口名.方法名调用。
从Java 8 开始接口允许定义默认方法注意是在接口, 格式 public default 返回值 方法名{方法体}从Java 8 开始接口允许定义静态方法。 public static 返回值 方法名{方法体}
接口名称。静态方法名(参数列表);
public interface Usb {//接口//接口中的抽象方法public abstract void a();//新添加的默认方法public default void b(){System.out.println(实现接口升级);}//新添加的静态方法public static void c(){System.out.println(实现静态方法);}
}
public class Usbfeng implements Usb{//实现类1Overridepublic void a() {System.out.println(Usbfeng);}
Override
public void b(){System.out.println(默认default覆盖写法);//重写默认b()方法完全可以最后实例化对象调用
} }
public class Usbshan implements Usb{//实现类二Overridepublic void a() {System.out.println(Usbshan);}
}1.接口的默认方法可以通过接口实现类对象直接调用
2.接口的默认方法也可以被接口实现类进行覆盖重写
public class Test {//测试类public static void main(String[] args) {
//创建了实现类对象Usbfeng usbfeng new Usbfeng();usbfeng.a();//调用抽象方法实现的是右侧实现类usbfeng.b();//调用默认方法如果实现类中没有会向上找接口Usbshan usbshan new Usbshan();usbshan.a();usbshan.b();//调用moUsb.c();}
}JDK9 接口新特性 private
我们需要抽取一个共有方法用来解决多个默认方法之间重复代码的问题但是这个共有方法不应该让实现类使用所以私有化
解决方案
从Java 9开始接口当中允许定义私有方法。
1.普通私有方法解决多个默认方法之间重复代码的问题。
private 返回值类型 方法名称参数列表{方法体
}public interface Typc {//代码重复率高public default void a(){System.out.println(默认方法A);System.out.println(AAA);System.out.println(BBB);System.out.println(CCC);}
public default void b(){System.out.println(默认方法B);System.out.println(AAA);System.out.println(BBB);System.out.println(CCC);
}
}
运用私有化后public interface Typc {//因为被私有化只有a和b能够使用c,其余的地方无法使用public default void a(){System.out.println(默认方法A);c();}public default void b(){System.out.println(默认方法B);c();}private void c(){System.out.println(AAA);System.out.println(BBB);System.out.println(CCC);}
}
测试public class Testtypec {public static void main(String[] args) {Typcc typcc new Typcc();typcc.b();typcc.a();}
}输出结果静态私有方法解决多个静态方法之间重复代码问题
private static 返回值类型 方法名称 参数列表{方法体
}静态私有方法同理只有本接口多个静态方法可以使用其余作用域无法使用。在Java9以后出现并使用JDK9 接口中可以使用 private 修饰方法供接口中其他方法调用。
抽象类和接口的区别重点
特性接口抽象类组合可以在新类中组合多个接口只能继承一个抽象类状态只含有静态字段、抽象方法、默认方法、静态方法可以包含字段默认方法和抽象方法默认方法不需要在子类里实现它只能引用接口中的方法抽象方法必须在子类里实现构造器不能有构造器接口没有构造、不能实例化有构造、同样不能实例化访问权限隐式 public可以为 protected 或包访问权限
举例
FunctionalInterface
interface IType {void test();
}
class Demo{public static void main(String[] args){// 通常使用 匿名类IType a new IType(){Overridepublic void test(){ // 实现}};// lambdaIType b () -{// 实现}; 如果lambda中实现只有一句代码则可以省略{}这种写法java可以根据变量的类型推断出匿名类实现的接口以及重写的方法。方法的写法上 如果方法没有参数则使用()表示。 如果有参数则需要在()写形参列表在实现中可以使用这些参数。 参数的类型可以省略可以推断出参数类型 如果方法没有参数则使用()表示。 如果只有一个参数()可以省略。
深克隆和浅克隆
浅克隆
浅克隆指创建一个新对象并将原始对象的所有非静态字段的值复制到新对象中。如果字段的类型是基本类型那么会复制其值如果字段的类型是引用类型则会复制引用即新对象和原始对象将引用同一个对象。
深克隆
深克隆是指创建一个新对象并将原始对象的所有字段新对象中包括引用类型字段所引用的对象。
简单来说就是浅克隆对象中的引用数据类型字段是同一个引用深克隆会比浅克隆多克隆一个引用数据类型
protected Person clone() throws CloneNotSupportedException {// return (Person) super.clone();Person copy (Person) super.clone();// 将引用数据类型 clone 一份 再设置Dog copyDog copy.getDog().clone();copy.dog copyDog;return copy;
}