温州 公司 网站艺术字体在线生成器免费转换器
- 作者: 五速梦信息网
- 时间: 2026年04月20日 07:16
当前位置: 首页 > news >正文
温州 公司 网站,艺术字体在线生成器免费转换器,深圳外贸网站建设,陶瓷 网站模板各位看官早安午安晚安呀 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 大家好我们今天来学习Java面向对象的的抽象类和接口#xff0c;我们大家庭已经来啦~ 第一次复习时总结#xff1a; 一#xff1a;抽象类
1.1… 各位看官早安午安晚安呀 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连小编尽全力做到更好 欢迎您分享给更多人哦 大家好我们今天来学习Java面向对象的的抽象类和接口我们大家庭已经来啦~ 第一次复习时总结 一抽象类
1.1:抽象类概念 在面向对象的概念中所有的对象都是通过类来描绘的但是反过来并不是所有的类都是用来描绘对象的 如果 一个类中没有包含足够的信息来描绘一个具体的对象这样的类就是抽象类 。 比如 在打印图形例子中 , 我们发现 , 父类 Shape 中的 draw 方法好像并没有什么实际工作 , 主要的绘制图形都是由 Shape的各种子类的 draw 方法来完成的 . 像这种没有实际工作的方法 , 我们可以把它设计成一个 抽象方 (abstract method) , 包含抽象方法的类我们称为 抽象类abstract class 1.2抽象类语法 // 抽象类被 abstract修饰的类 抽象类也是类也可以增加普通方法和属性 public abstract class Shape { public int a // 抽象方法被abstract修饰的方法没有方法体 abstract public void draw (); } 1.3 抽象类特性 1. 抽象类不能直接实例化对象 2. 抽象方法不能被 privatefinalstatic修饰因为抽象方法要被子类重写private只能在自己的类里面使用密封方法 final不能被继承和static静态方法不依赖对象 3抽象类必须被继承并且继承后子类要重写父类中的抽象方法否则子类也是抽象类必须要使用 abstract 修饰子类的子类要重写你俩的抽象方法出来混迟早都要还的 4被重写的方法不能比父类的访问权限更低这是重写的要求 4. 抽象类中不一定包含抽象方法但是有抽象方法的类一定是抽象类 5. 抽象类中可以有构造方法供子类创建对象时初始化父类的成员变量 第三条我说明一下 abstract class Shape{public int a;public abstract void draw();}
abstract class A extends Shape{public abstract void test(); }
class B extends A{Overridepublic void test() {}Overridepublic void draw() {}
} 只单独一个抽象方法也可以不过这继承毫无意义呀 abstract class A extends Shape{} 1.4抽象类的作用 抽象类就是为了被继承多了一层校验 抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法. 有些同学可能会说了, 普通的类也可以被继承呀, 普通的方法也可以被重写呀, 为啥非得用抽象类和抽象方法呢? 确实如此. 但是使用抽象类相当于多了一重编译器的校验 使用抽象类的场景就如上面的代码 , 实际工作不应该由父类完成 , 而应由子类完成 . 那么此时如果不小心误用成父类 了, 使用普通类编译器是不会报错的 . 但是父类是抽象类就会在实例化的时候提示错误 , 让我们尽早发现问题 . 很多语法存在的意义都是为了 预防出错, 例如我们曾经用过的 final 也是类似 . 创建的变量用户不去修改 , 不就相当于常量嘛? 但是加上 final 能够在不小心误修改的时候 , 让编译器及时提醒我们 . 充分利用编译器的校验, 在实际开发中是非常有意义的. 二接口 2.1 接口的概念 抽象类是特别类接口是特殊的抽象类限制更多就是利用向上转型向下转型动态绑定 在现实生活中接口的例子比比皆是比如笔记本上的 USB 口电源插座等。 2.2接口的语法 接口的定义格式与定义类的格式基本相同将 class 关键字换成 interface 关键字就定义了一个接口 public interface 接口名称 { // 抽象方法 public abstract void method1 (); // public abstract 是固定搭配可以不写一般都不写但是默认有 成员变量默认被public static final 修饰 public void method2 (); abstract void method3 (); 这两种真不好 void method4 (); // 注意在接口中上述写法都是抽象方法跟推荐方式4代码更简洁 } 2.3 接口使用 注意子类和父类之间是 extends 继承关系类与接口之间是 implements 实现关系。 我们一般说实现接口继承父类 接口不能直接使用必须要有一个 实现类 来 实现 该接口实现接口中的所有抽象方法 public class 类名称 implements 接口名称 { // … } 接下来我们利用接口实现一个操作 请实现笔记本电脑使用 USB 鼠标、 USB 键盘的例子 1. USB 接口包含打开设备、关闭设备功能 2. 笔记本类包含开机功能、关机功能、使用 USB 设备功能 3. 鼠标类实现 USB 接口并具备点击功能 4. 键盘类实现 USB 接口并具备输入功能 // USB接口
//
interface USB {void openDevice();//默认被 public abstract修饰void closeDevice();
}
// 鼠标类实现USB接口
class Mouse implements USB {Overridepublic void openDevice() {System.out.println(打开鼠标);}Overridepublic void closeDevice() {System.out.println(关闭鼠标);}public void click(){System.out.println(鼠标点击);}
}
// 键盘类实现USB接口
class KeyBoard implements USB {Overridepublic void openDevice() {System.out.println(打开键盘);}Overridepublic void closeDevice() {System.out.println(关闭键盘);}public void inPut(){System.out.println(键盘输入);}
}
// 笔记本类使用USB设备
class Computer {public void powerOn(){System.out.println(打开笔记本电脑);}public void powerOff(){System.out.println(关闭笔记本电脑);}public void useDevice(USB usb){//传鼠标或者键盘的引用,向上转型usb.openDevice();if(usb instanceof Mouse){//Mouse mouse (Mouse)usb;//向下转型mouse.click();//实现鼠标特有的功能}else if(usb instanceof KeyBoard){KeyBoard keyBoard (KeyBoard)usb;//向下转型keyBoard.inPut();//实现键盘特有的功能}usb.closeDevice();}
}
// 测试类
public class TestUSB {public static void main(String[] args) {Computer computer new Computer();computer.powerOn();//打开笔记本电脑
// 使用鼠标设备computer.useDevice(new Mouse());//
// 使用键盘设备computer.useDevice(new KeyBoard());computer.powerOff();//关闭笔记本电脑}
}2.4.接口特点 抽象类前4条她都有但是接口有更多的特点不然怎么是特殊的抽象类呢小编自己说的 前四条差不多 1. 接口类型是一种引用类型但是不能直接 new 接口的对象不能实例化对象 2. 如果类没有实现接口中的所有的抽象方法则类必须设置为抽象类和抽象类差不多 3 抽象方法不能被 privatefinalstatic修饰 4. 重写接口中方法时不能使用默认的访问权限不能比接口里面的方法的访问权限更低 5接口中的方法默认被public abstract 修饰成员变量默认被 public static final 修饰不加也默认其他修饰符会报错 6. 接口中不能有静态代码块和构造方法这一点抽象类可以有这些 7. 接口虽然不是类但是接口编译完成后字节码文件的后缀格式也是 .class USB接口 8. jdk8中接口中还可以包含 default 方法。 2.5实现多个接口 在 Java 中类和类之间是单继承的一个类只能有一个父类即 Java中不支持多继承但是一个类可以实现多个接口 。下面通过类来表示一组动物 首先我定义一个动物类就只定义变量大家公用嘛活动让子类通过实现接口来重写 class Animal {protected String name;public Animal(String name) {this.name name;}
} 然后我定义游泳跑步飞的接口方法我没有方法体让动物们来实现 interface IFlying {void fly();
}
interface IRunning {void run();
}
interface ISwimming {void swim();
} 接下来我要定义几个动物猫, 是会跑的 class Cat extends Animal implements IRunning {public Cat(String name) {super(name);}Overridepublic void run() {System.out.println(this.name 正在用猫腿跑);}
} 鱼, 是会游的. class Fish extends Animal implements ISwimming {public Fish(String name) {super(name);}Overridepublic void swim() {System.out.println(this.name 正在用尾巴游泳);}
} 青蛙还是两栖的呢既会跑又会游泳那就实现两个接口 class Frog extends Animal implements IRunning, ISwimming {public Frog(String name) {super(name);}Overridepublic void run() {System.out.println(this.name 正在蛙跳);}Overridepublic void swim() {System.out.println(this.name 正在蹬腿游泳);}
} 鸭子会跑会游泳会飞实现三个接口 class Duck extends Animal implements IRunning, ISwimming, IFlying {public Duck(String name) {super(name);}Overridepublic void fly() {System.out.println(this.name 正在用鸭翅膀飞);}Overridepublic void run() {System.out.println(this.name 正在用鸭腿跑);}Overridepublic void swim() {System.out.println(this.name 正在漂在水上);}
} 上面的代码展示了 Java 面向对象编程中最常见的用法 : 一个类继承一个父类, 同时实现多种接口 超级重要 接下来就是向上转型 只要是你实现了这个IRunning接口就可以被IRunning引用你的对象你只需要把你的引用传过来就发生了向上转型 然后我传过去猫猫,青蛙鸭子这些对象的引用利用向上转型 一个引用传递过来的对象不同所表现的行为不同这就是多态的思想 public class TestInterface {public static void running(IRunning iRunning){iRunning.run();}public static void main(String[] args) {Cat cat new Cat(猫猫);running(cat);Duck duck new Duck(鸭子);running(duck);Frog frog new Frog(青蛙);running(frog);}
} 甚至机器人只要实现了这个接口他也可以通过这个引用实现这个动作只要实现了这个接口和是不是动物没关系 Robot robot new Robot();running(robot);class Robot implements IRunning{Overridepublic void run(){System.out.println(正在用机器腿跑);}
} 这样设计有什么好处呢 ? 时刻牢记多态的好处 , 让程序猿 忘记类型 . 有了接口之后, 类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力 2.6 接口间的继承 类与类之间的继承只能单继承但是接口之间的继承可以多继承相当于把多个接口合并在了一起一个类也能继承多个接口 说到合并静态代码块也是合并 接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字 interface IRunning {void run();
}
interface ISwimming {void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
…
} 2.7抽象类和接口的区别 抽象类和接口都是 Java 中多态的常见使用方式 二者的区别前面我也讲述了一下下面呢 通过表格再说一下 核心区别 : 抽象类中可以包含普通方法和普通字段,这样的普通方法和字段可以被子类直接使用 ( 不必重写 )而且抽象类里面有构造方法 而接口中不能包含普通方法, 子类必须重写所有的抽象方法而且成员变量都是全局常量接口里面没有构造方法 如之前写的 Animal 例子 . 此处的 Animal 中包含一个 name 这样的属性 , 这个属性在任何子类中都是存在的 . 因此 此处的 Animal 只能作为一个抽象类 , 而不应该成为一个接口 class Animal {protected String name;public Animal(String name) {this.name name;}
} 三object类 Object 是 Java 默认提供的一个类。 Java里面除了Object 类所有的类都是存在继承关系的。默认会继承 Object类 。即所有类的对象都可以使用Object 的引用进行接收。 例如 所以在开发之中 Object 类是参数的最高统一类型。但是 Object 类也存在有定义好的一些方法。如下 我们先了解这几种方法 3.1equals方法 首先我们看一下object类里面实现的equals方法很显然就是两个引用在比较就是比较两个地址是否一样 既然是这样那么这个equals方法就和普通的比较没什么区别了所以只要我们要用的话就只能重写这个方法除非你就想这么用 public static void main(String[] args) {Person person1 new Person(zhangsan,18);Person person2 new Person(zhangsan,18);Person person3 person1;System.out.println(person1 person2);//其实就是两个引用在比较//那我们换equals方法来比较呢System.out.println(person1.equals(person2));//falseSystem.out.println(person1.equals(person3));地址相等才相等你来指向一个对象}那么我们就重新写一下这个方法 Overridepublic boolean equals(Object obj) {//返回true或者falseif (obj null) {return false ;}if(this obj) {return true ;}
// 不是Person类对象if (!(obj instanceof Person)) {//判断obj是否是Person的实例obj这个引用是否指向了Person类的对象return false ;}Person person (Person) obj ; // 向下转型比较属性值return this.name.equals(person.name) this.ageperson.age ;}} 接下来再运行一下 显然就可以了 3.2.hascode方法 回忆刚刚的toString方法的源码 public String toString () { return getClass (). getName () Integer . toHexString ( hashCode ());进化过处理的地址 } hashCode() 这个方法帮我们算了一个具体的 对象位置 这里面涉及数据结构但是我们还没学数据结构没法讲述所以我们只能说它是个内存地址。然后调用Integer.toHexString() 方法将这个地址以 16 进制输出 hashcode方法源码(该方法是一个 native 方法底层是由 C/C 代码写的。我们看不到) 示例 Person person1 new Person(zhangsan,18);Person person2 new Person(zhangsan,18);System.out.println(person1.hashCode());System.out.println(person2.hashCode()); 但是我们想要把两个名字相同年龄相同的对象存储在同一个位置这个时候我们就要重写hashcode(方法了 结果 总结 hashcode方法用来确定对象在内存中存储的位置是否相同equals方法用来确定该对象的内容是否一样我们重写的 四比较两个对象的大小以及排序对象数组
4.1比价两个对象的大小
引用类型不能直接这么比较
public class Test{public static void main(String[] args) {Student student1 new Student(zhangsan,18);Student student2 new Student(zhangsan,18);//System.out.println(student1 student2);//引用类型不能这样比较}
}
如果要比较的话要实现一个接口并且重写它的比较方法 class Student implements ComparableStudent {String name;int age;public Student(String name, int age) {this.name name;this.age age;}Overridepublic int compareTo(Student o) {return this.age - o.age;}
} Student student1 new Student(zhangsan,18);Student student2 new Student(zhangsan,12);System.out.println(student1.compareTo(student2));//结果为6 比较名字大小的时候我们直接可以用String类的CompareTo进行比较String类已经对它进行重写了后面在认识String类的时候我会讲到 System.out.println(student1.name.compareTo(student2.name)); 4.2排序对象数组 我们就用数组排序的方法Arrays.sort排序 public static void main(String[] args) {Student []students new Student[3];students[0] new Student(zhangsan,18);students[1] new Student(wangwu,20);students[2] new Student(lisi,17);Arrays.sort(students);System.out.println(Arrays.toString(students));
} 但是编译器报错了你要排序但是你要按照什么排序呢年龄还是名字 这里我们可以看到他要把数组里边的元素类型强转为Comparable类型所以我们就要去建立这个联系实现这个接口 在 sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象. package Demo1;import java.util.Arrays;class Student implements ComparableStudent {String name;int age;public Student(String name, int age) {this.name name;this.age age;}Overridepublic String toString() {return Student{ name name \ , age age };}Overridepublic int compareTo(Student o) {return this.age - o.age;}
}
public class Test {public static void main(String[] args) {Student[] students new Student[3];students[0] new Student(zhangsan, 18);students[1] new Student(wangwu, 20);students[2] new Student(lisi, 17);Arrays.sort(students);System.out.println(Arrays.toString(students));}
}结果 在 sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象. 4.3我们自己实现一个模拟实现一个冒泡排序呢
注意单独比较年龄或者姓名之后这个类整体会被交换而不是单独交换年龄或者姓名你们一起被交换 public class Test {public static void bubbleSort(Comparable []comparables){for (int i 0; i comparables.length-1; i) {int flag 1;for (int j 0; j comparables.length-1-i; j) {//这个明显是错误的要去全部转换啊Comparable 类型没有age这个变量这个就是一个向上转型/int tmp 0;tmp comparables[i].age;comparables[i].age comparables[i1].age;comparables[i1].age tmp;flag -1;/if( comparables[i].compareTo(comparables[i1]) 0){Comparable tmp comparables[i];comparables[i1] comparables[i];comparables[i] tmp;flag -1;}}if(flag 1){break;}}}public static void main(String[] args) {Student[] students new Student[3];students[0] new Student(zhangsan, 18);students[1] new Student(wangwu, 20);students[2] new Student(lisi, 17);bubbleSort(students);System.out.println(Arrays.toString(students));/Arrays.sort(students);System.out.println(Arrays.toString(students));/}
}或者我们根本就不用实现接口呢其实是因为String类帮我们实现过了 用String类的compareTo方法 public class Test {public static void bubbleSort1(Student[]students){for (int i 0; i students.length-1; i) {int flag 1;for (int j 0; j students.length - 1 - i; j) {if (students[j].name.compareTo(students[j 1].name) 0) {Student tmp students[j];students[j] students[j 1];students[j 1] tmp;flag -1;}}if(flag 1){break;}}} Comparable接口的耦合性是比较强的 当一个类实现了 Comparable 接口它的比较逻辑就被硬编码在了类的定义中。这意味着如果需要改变比较逻辑你必须修改这个类的源代码。这种实现方式的耦合性较强 目前我理解的是因为Comparable的里的方法是compareTo但是要比较名字的时候Student实现Comparable接口重写compareTo方法你怎么在这个方法里面去比较字符串大小字符串大小比较需要String类重写的 compareTo方法去比较 总不能compareTo里面嵌套compareTo吧 这个时候我们就需要一个实现 另一个接口Comparator接口提供了更大的灵活性和解耦能力 具体实现 class NameComparator implements ComparatorStudent{Overridepublic int compare(Student o1, Student o2) {return o1.name.compareTo(o2.name);}
}
class AgeComparator implements ComparatorStudent{Overridepublic int compare(Student o1, Student o2) {return o1.age - o2.age;}
}public static void main(String[] args) {Student[] students new Student[3];students[0] new Student(zhangsan, 18);students[1] new Student(wangwu, 20);students[2] new Student(lisi, 17);AgeComparator ageComparator new AgeComparator();System.out.println(ageComparator.compare(students[0], students[1]));NameComparator nameComparator new NameComparator();System.out.println(nameComparator.compare(students[0], students[1]));}
}冒泡呢就改了比较大小的呗交换的步骤都不变 public static void bubbleSort2(Student[]students){for (int i 0; i students.length-1; i) {int flag 1;for (int j 0; j students.length - 1 - i; j) {NameComparator nameComparator new NameComparator();if (nameComparator.compare(students[j],students[j1]) 0) {Student tmp students[j];students[j] students[j 1];students[j 1] tmp;flag -1;}}if(flag 1){break;}}} 五克隆 浅拷贝 深拷贝
class Money implements Cloneable{int m;public Money(int m) {this.m m ;}Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}public class clonePreviousTest {public static void main(String[] args) throws CloneNotSupportedException {Person person1 new Person(liHua, 18,new Money(10));Person person2 (Person) person1.clone();person1.money.m 100;System.out.println(person1.money.m);System.out.println(person2.money.m);}
}
class Person implements Cloneable {String name;int age;Money money;Overrideprotected Object clone() throws CloneNotSupportedException {Person tmp (Person) super.clone();tmp.money (Money) this.money.clone();return tmp;}public Person(String name, int age,Money money) {this.name name;this.age age;this.money money;}Overridepublic String toString() {return Person{ name name \ , age age };}
} 深拷贝这里就是全部都进行了拷贝包括我们自定义的类型的值由于异常我们现在还没有学习具体的克隆我们放在异常的那一节进行讲解~~~ 上述就是 Java面向对象之多态的全部内容了能看到这里相信您一定对小编的文章有了一定的认可接口的出现其实也是一个老大带几个小弟的过程我们的大家庭就这么水灵灵的又增加啦~ 有什么问题欢迎各位大佬指出 欢迎各位大佬评论区留言修正 您的支持就是我最大的动力
相关文章
-
温岭市市住房和城乡建设规划局网站wordpress密码加密方式
温岭市市住房和城乡建设规划局网站wordpress密码加密方式
- 技术栈
- 2026年04月20日
-
温江做网站的公司网站网络营销公司
温江做网站的公司网站网络营销公司
- 技术栈
- 2026年04月20日
-
温江建设局备案网站网站访问量的单位
温江建设局备案网站网站访问量的单位
- 技术栈
- 2026年04月20日
-
温州seo网站推广百度怎样收录到网站
温州seo网站推广百度怎样收录到网站
- 技术栈
- 2026年04月20日
-
温州大都市建设开发有限公司网站工业产品设计流程图
温州大都市建设开发有限公司网站工业产品设计流程图
- 技术栈
- 2026年04月20日
-
温州阀门网站建设遵义网站制作教程
温州阀门网站建设遵义网站制作教程
- 技术栈
- 2026年04月20日






