Java学习第十天内容:
一、接口
二、多态
一、接口
理解:接口是一套公共的规范标准
public:修饰的方法–>该方法可以被跨包访问
protected:修饰的方法–>该方法可以被子类访问
private:修饰的方法–>该方法只能被其所在类中的其他方法访问
接口的发展:
接口的定义格式:
public interface 接口名{
//1.定义抽象方法:默认被public abstract修饰 【可以省略public abstract】
//2.定义默认方法:需要被public和 default(是关键词要写出来和抽象类中的普通方法一样只是通过default关键字做标记) 【可以省略public】
//3.定义静态方法:需要被public和static修饰 【直接接口名调用】
//4.定义私有方法:被private修饰的方法 【只能在本接口中使用】
//5.定义常量: 默认被public static final修饰【public static final可以省略】
}
接口的实现(implements)
public class 类名 implements 接口名{
//1.接口中的抽象方法:必须在其实现类中被重写(复写)
//2.接口中的默认方法:可选复写(可写可不写)
}
接口的使用步骤:
接口和抽象类的比较:
抽象类与接口对比的图解:
类与类、类与接口、接口与接口
- 类与类:单一的继承关系(抽象类也是这样)–>儿子只能有一个亲爹
- 类与接口:多实现关系 -->儿子可以有多个干爹
- 接口与接口:多继承关系
抽象类和普通父类都是属于类的概念,只能被单继承,二者不能被同时继承,但是可以分别和接口一同实现–>子类可以继承父类(或抽象类)同时还可以实现接口
接口和抽象类都不能直接被创建对象所以没有构造器
接口与抽象类的使用
- 抽象类:抽取子类的共性内容–>(和子类的关系是纵向的)
- 接口:给类做功能扩展–>(和实现类(类似于子类为了区分才叫实现类以及用implements关键字修饰)的关系是横向的)
接口和抽象类是一种互补关系,在开发中根据实际需求合理运用
抽象类中抽象方法的定义方式:
二、多态
理解:
一个对象有多种数据类型;
多态体现的就是一种子类和父类的可以灵活转换关系,所以多态的实现要基于继承;
多态就是去调用子类的重写的方法(不是变量)体现不同的结果这就是多态。
多态的特性使得方法的调用变得更加灵活,这也是面向对象概念(面向对象的程序设计思想)的核心体现
这么做的核心目的:
就是为了简化代码,提高程序的复用性,性能,效率,可维护性
实现多态的前提:
- 类与类之间存在子-父类关系
- 子类中重写父类的方法
- 父类接收子类的对象
如:
Animal a= new Dog();
Animal a= new Cat();
多态成员的访问特点:
- 成员变量:只看父类,父类没有就报错
- 成员方法:如果子类中有方法的重写,就优先执行子类的重写的方法,否则就看父类,父类有就执行,父类没有就报错
【小结:有方法的重写才执行子类,没有重写都执行父类】
多态的好处:
把父类/接口,作为方法的参数,调用方法的时候可以传递任意的子类/实现类的对象。
//举例:养动物
public void feed(Animal a){//参数Animal a 既能接收子类Dog,也能接收子类Cat对象(只要是Animal的子类对象,都可以接受)
a.eat();
}
多态的弊端:
不能调用其实现类的特有的方法,只能调用实现类中重写的方法–>为了解决这种弊端–>向上转型和向下转型(类型转换只能发生在子类与父类之间–>是一种纵向类型转换,不支持横向类型转换(即子类之间不能转换))–>因此引入 ==instanceof ==方法结合 if-else 来判断对象类型,以免发生同级类之间的类型转换(报类型转换异常)
知识点小记:
- final关键字修饰的常量,其常量名建议全部大写,如果有多个单词用下划线分隔(只是一种编程约定,也可以写小写,只是为了做区分才大写的)
- 工具类里的方法都是静态方法,只含静态方法的类就是工具类;
- 被static关键字修饰的方法不能有this关键字,存在先后关系——因为static修饰的方法是类的方法可以被该类的所有对象调用,随着类被加载而被加载,this关键字是属于对象的,哪个对象调用这个方法,那么这个方法就是属于被这个对象调用
- 成员变量不能被覆盖重写,只有方法才可以
- Java中的任何一个类(包括自定义的类),默认extends Object,直接或间接是Object类的子类,(object类是根类)
- 常量池中常量的存储也是基于数组实现的
- 接口也可以作为多态体现
- 驱动就是一种程序:
每种硬件(如鼠标、键盘、U盘…)都有自己的驱动程序,让电脑和硬件建立连接,从而实现硬件和电脑的交互 - 为了System.out.println();可以打印任何数据类型?
底层源码:
public void println(Object x) {//参数列表是Object 类型(根类)-->表示可以接收任何数据类型
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
方法的重写和方法的重载比较:
方法的重写也就是子类重写了父类中的方法(纵向关系)
方法的重载就是同一类中同名,而参数列表不同的方法(横向关系)(方法之间的是否重载,只看方法名是否相同参数列表是否不同–>有无参数,参数个数,参数类型)与方法的返回值类型,或权限修饰符无关
访问成员变量的两种方式:
代码练习:
有一个老师很厉害什么都会,能教Java学生、能教UI学生、还能教Php学生
有一天来了一个想学Java的学生,老师就教这个学生学习Java
有一天来了一个想学UI的学生,老师就教这个学生学习UI
有一天来了一个想学Php的学生,老师就教这个学生学习Php
有一天来了一群学生,老师就开班教这一群学生学习。
学习Java的学生要多学一门课程JavaScript
请用面向对象的思维,分析以上描述中有哪些类、哪些是父类、哪些是接口。
运用继承、抽象类、多态、接口、等相关知识设计它们之间的关系,并用代码体现出来。
分析有哪些类和方法:
1. 看有哪些名词,就有哪些类 (名词提炼法)
如:老师类、学生类、Java学生类、UI学生类、Php学生类。
-
看有哪些动词,就有哪些方法;动作是由谁发出的,这个方法就是在哪个类中
//如:【教】这个动作,是【老师】发出来的。
public class 老师类{
//教一个学生(一个学生,就是一个学生对象)
public void 教(学生 s){
…
}//教一群学生((一群学生,就是好多个学生对象)
public void 教(ArrayList<学生> list){
…
}
}//如:【学习】这个动作,是【学生】发出来的
public abstract class 学生类{
//学生学习,不知道什么就写成抽象的。
publ
思维图解:
抽象类-students类
package com.itheima.practice;
public abstract class Students {
public abstract void study();
}
子类-JavaStudents
package com.itheima.practice;
public class JavaStudent extends Students implements Skill{
@Override
public void study() {
System.out.println("Java学生学Java!");
}
//java学习的特有方法
@Override
public void javaScript() {
System.out.println("Java学生还要学JavaScript。");
}
}
子类-PHPStudent
package com.itheima.practice;
public class PHPStudent extends Students {
@Override
public void study() {
System.out.println("PHP学生学PHP!");
}
}
子类-UIStudent
package com.itheima.practice;
public class UIStudent extends Students {
@Override
public void study() {
System.out.println("UI学生学UI!");
}
}
接口-Skill
package com.itheima.practice;
public interface Skill {
public abstract void javaScript();
}
Teacher类
package com.itheima.practice;
import java.util.ArrayList;
public class Teacher {
public void teach(Students students){
if(students instanceof JavaStudent){
JavaStudent javaStudent = (JavaStudent)students;
javaStudent.study();
javaStudent.javaScript();//javaStudent的特有方法
System.out.println("-----------");
}else {
students.study();
}
}
public void teach(ArrayList<Students> list){//方法的重载
for (int i = 0; i < list.size(); i++) {
Students students = list.get(i);//拿到的任何学生对象都交给父类Student类的变量接收--多态的体现
teach(students);
}
}
}
测试类-Demo
package com.itheima.practice;
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
Students javaStudent = new JavaStudent();
Students uiStudent = new UIStudent();
Students phpStudent = new PHPStudent();
Teacher teacher = new Teacher();
teacher.teach(javaStudent);
teacher.teach(phpStudent);
teacher.teach(uiStudent);
System.out.println("-------------------");
//一群学生
ArrayList<Students> list = new ArrayList<>();
list.add(javaStudent);
list.add(phpStudent);
list.add(uiStudent);
teacher.teach(list);
}
}
运行结果:
Java学生学Java!
Java学生还要学JavaScript。
-----------
PHP学生学PHP!
UI学生学UI!
-------------------
Java学生学Java!
Java学生还要学JavaScript。
PHP学生学PHP!
UI学生学UI!
Java学习第十一天内容链接:
https://blog.youkuaiyun.com/LJN951118/article/details/88983652