1:final关键字(掌握)
(1)是最终的意思,可以修饰类,方法,变量。
(2)特点:
- A:它修饰的类,不能被继承。
- B:它修饰的方法,不能被重写。
- C:它修饰的变量,是一个常量。
(3)面试相关:
A:局部变量
a:基本类型 值不能发生改变
b:引用类型 地址值不能发生改变,但是对象的内容是可以改变的
B:初始化时机
a:只能初始化一次。
b:常见的给值
定义的时候。(推荐)
构造方法中。
2:多态(掌握)
(1)同一个对象在不同时刻体现出来的不同状态。
(2)多态的前提:
- A:有继承或者实现关系。
- B:有方法重写。
- C:有父类或者父接口引用指向子类对象。
多态的分类:
a:具体类多态
class Fu {}
class Zi extends Fu {}
Fu f = new Zi();
b:抽象类多态
abstract class Fu {}
class Zi extends Fu {}
Fu f = new Zi();
c:接口多态
interface Fu {}
class Zi implements Fu {}
Fu f = new Zi();
(3)多态中的成员访问特点
A:成员变量
编译看左边,运行看左边
B:构造方法
子类的构造都会默认访问父类构造
C:成员方法
编译看左边,运行看右边
D:静态方法
编译看左边,运行看左边
为什么?
因为成员方法有重写。
(4)多态的好处:
A:提高代码的维护性(继承体现)
B:提高代码的扩展性(多态体现)
(5)多态的弊端:
父不能使用子的特有功能。
现象:
子可以当作父使用,父不能当作子使用。
(6)多态中的转型
A:向上转型
从子到父
B:向下转型
从父到子
(7)孔子装爹的案例帮助大家理解多态
多态的问题理解: class 孔子爹 { public int age = 40; public void teach() { System.out.println("讲解JavaSE"); } } class 孔子 extends 孔子爹 { public int age = 20; public void teach() { System.out.println("讲解论语"); } public void playGame() { System.out.println("英雄联盟"); } } //Java培训特别火,很多人来请孔子爹去讲课,这一天孔子爹被请走了 //但是还有人来请,就剩孔子在家,价格还挺高。孔子一想,我是不是可以考虑去呢? //然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。就开始装爹 //向上转型 孔子爹 k爹 = new 孔子(); //到人家那里去了 System.out.println(k爹.age); //40 k爹.teach(); //讲解论语 //k爹.playGame(); //这是儿子才能做的 //讲完了,下班回家了 //脱下爹的装备,换上自己的装备 //向下转型 孔子 k = (孔子) k爹; System.out.println(k.age); //20 k.teach(); //讲解论语 k.playGame(); //英雄联盟
(8)多态的练习
A:猫狗案例
/* 多态练习:猫狗案例 */ class Animal { public void eat(){ System.out.println("吃饭"); } } class Dog extends Animal { public void eat() { System.out.println("狗吃肉"); } public void lookDoor() { System.out.println("狗看门"); } } class Cat extends Animal { public void eat() { System.out.println("猫吃鱼"); } public void playGame() { System.out.println("猫捉迷藏"); } } class DuoTaiTest { public static void main(String[] args) { //定义为狗 Animal a = new Dog(); a.eat(); System.out.println("--------------"); //还原成狗 Dog d = (Dog)a; d.eat(); d.lookDoor(); System.out.println("--------------"); //变成猫 a = new Cat(); a.eat(); System.out.println("--------------"); //还原成猫 Cat c = (Cat)a; c.eat(); c.playGame(); System.out.println("--------------"); //演示错误的内容 //Dog dd = new Animal(); //Dog ddd = new Cat(); //ClassCastException //Dog dd = (Dog)a; } }
B:南方人和北方人案例
/* 不同地方饮食文化不同的案例 */ class Person { public void eat() { System.out.println("吃饭"); } } class SouthPerson extends Person { public void eat() { System.out.println("炒菜,吃米饭"); } public void jingShang() { System.out.println("经商"); } } class NorthPerson extends Person { public void eat() { System.out.println("炖菜,吃馒头"); } public void yanJiu() { System.out.println("研究"); } } class DuoTaiTest2 { public static void main(String[] args) { //测试 //南方人 Person p = new SouthPerson(); p.eat(); System.out.println("-------------"); SouthPerson sp = (SouthPerson)p; sp.eat(); sp.jingShang(); System.out.println("-------------"); //北方人 p = new NorthPerson(); p.eat(); System.out.println("-------------"); NorthPerson np = (NorthPerson)p; np.eat(); np.yanJiu(); } }
面试题
/* 看程序写结果:先判断有没有问题,如果没有,写出结果 多态的成员访问特点: 方法:编译看左边,运行看右边。 继承的时候: 子类中有和父类中一样的方法,叫重写。 子类中没有父亲中出现过的方法,方法就被继承过来了。 */ class A { public void show() { show2(); } public void show2() { System.out.println("我"); } } class B extends A { /* public void show() { show2(); } */ public void show2() { System.out.println("爱"); } } class C extends B { public void show() { super.show(); } public void show2() { System.out.println("你"); } } public class DuoTaiTest4 { public static void main(String[] args) { A a = new B(); a.show(); B b = new C(); b.show(); } }
答案:没有问题,结果:爱你
3:抽象类(掌握)
(1)把多个共性的东西提取到一个类中,这是继承的做法。
但是呢,这多个共性的东西,在有些时候,方法声明一样,但是方法体。
也就是说,方法声明一样,但是每个具体的对象在具体实现的时候内容不一样。
所以,我们在定义这些共性的方法的时候,就不能给出具体的方法体。
而一个没有具体的方法体的方法是抽象的方法。
在一个类中如果有抽象方法,该类必须定义为抽象类。
(2)抽象类的特点
A:抽象类和抽象方法必须用关键字abstract修饰
B:抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类
C:抽象类不能实例化
D:抽象类的子类
a:是一个抽象类。
b:是一个具体类。这个类必须重写抽象类中的所有抽象方法。
(3)抽象类的成员特点:
A:成员变量
有变量,有常量
B:构造方法
有构造方法
C:成员方法
有抽象,有非抽象
(4)抽象类的练习
A:猫狗案例练习
/* 猫狗案例 具体事物:猫,狗 共性:姓名,年龄,吃饭 分析:从具体到抽象 猫: 成员变量:姓名,年龄 构造方法:无参,带参 成员方法:吃饭(猫吃鱼) 狗: 成员变量:姓名,年龄 构造方法:无参,带参 成员方法:吃饭(狗吃肉) 因为有共性的内容,所以就提取了一个父类。动物。 但是又由于吃饭的内容不一样,所以吃饭的方法是抽象的, 而方法是抽象的类,类就必须定义为抽象类。 抽象动物类: 成员变量:姓名,年龄 构造方法:无参,带参 成员方法:吃饭(); 实现:从抽象到具体 动物类: 成员变量:姓名,年龄 构造方法:无参,带参 成员方法:吃饭(); 狗类: 继承自动物类 重写吃饭(); 猫类: 继承自动物类 重写吃饭(); */ //定义抽象的动物类 abstract class Animal { //姓名 private String name; //年龄 private int age; public Animal() {} public Animal(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //定义一个抽象方法 public abstract void eat(); } //定义具体的狗类 class Dog extends Animal { public Dog() {} public Dog(String name,int age) { super(name,age); } public void eat() { System.out.println("狗吃肉"); } } //定义具体的猫类 class Cat extends Animal { public Cat() {} public Cat(String name,int age) { super(name,age); } public void eat() { System.out.println("猫吃鱼"); } } //测试类 class AbstractTest { public static void main(String[] args) { //测试狗类 //具体类用法 //方式1: Dog d = new Dog(); d.setName("旺财"); d.setAge(3); System.out.println(d.getName()+"---"+d.getAge()); d.eat(); //方式2: Dog d2 = new Dog("旺财",3); System.out.println(d2.getName()+"---"+d2.getAge()); d2.eat(); System.out.println("---------------------------"); Animal a = new Dog(); a.setName("旺财"); a.setAge(3); System.out.println(a.getName()+"---"+a.getAge()); a.eat(); Animal a2 = new Dog("旺财",3); System.out.println(a2.getName()+"---"+a2.getAge()); a2.eat(); //练习:测试猫类 } }
B:老师案例练习
/* 老师案例 具体事物:基础班老师,就业班老师 共性:姓名,年龄,讲课。 分析: 基础班老师 姓名,年龄 讲课。 就业班老师 姓名,年龄 讲课。 实现: 老师类 基础班老师 就业班老师 */ //定义抽象的老师类 abstract class Teacher { //姓名 private String name; //年龄 private int age; public Teacher() {} public Teacher(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //抽象方法 public abstract void teach(); } //基础班老师类 class BasicTeacher extends Teacher { public BasicTeacher(){} public BasicTeacher(String name,int age) { super(name,age); } public void teach() { System.out.println("基础班老师讲解JavaSE"); } } //就业班老师类 class WorkTeacher extends Teacher { public WorkTeacher(){} public WorkTeacher(String name,int age) { super(name,age); } public void teach() { System.out.println("就业班老师讲解JavaEE"); } } class AbstractTest2 { public static void main(String[] args) { //具体的类测试,自己玩 //测试(多态) //基础班老师 Teacher t = new BasicTeacher(); t.setName("刘意"); t.setAge(30); System.out.println(t.getName()+"---"+t.getAge()); t.teach(); System.out.println("--------------"); t = new BasicTeacher("刘意",30); System.out.println(t.getName()+"---"+t.getAge()); t.teach(); System.out.println("--------------"); //就业班老师 t = new WorkTeacher(); t.setName("林青霞"); t.setAge(27); System.out.println(t.getName()+"---"+t.getAge()); t.teach(); System.out.println("--------------"); t = new WorkTeacher("林青霞",27); System.out.println(t.getName()+"---"+t.getAge()); t.teach(); } }
C:学生案例练习
/* 学生案例 具体事务:基础班学员,就业班学员 共性:姓名,年龄,班级,学习,吃饭 分析: 基础班学员 成员变量:姓名,年龄,班级 成员方法:学习,吃饭 就业班学员 成员变量:姓名,年龄,班级 成员方法:学习,吃饭 得到一个学员类。 成员变量:姓名,年龄,班级 成员方法:学习,吃饭 实现: 学员类 基础班学员 就业班学员 */ //定义抽象学员类 abstract class Student { //姓名 private String name; //年龄 private int age; //班级 private String grand; public Student() {} public Student(String name,int age,String grand) { this.name = name; this.age = age; this.grand = grand; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGrand() { return grand; } public void setGrand(String grand) { this.grand = grand; } //学习 public abstract void study(); //吃饭 public void eat() { System.out.println("学习累了,就该吃饭"); } } //具体基础班学员类 class BasicStudent extends Student { public BasicStudent() {} public BasicStudent(String name,int age,String grand) { super(name,age,grand); } public void study() { System.out.println("基础班学员学习的是JavaSE"); } } //具体就业班学员类 class WorkStudent extends Student { public WorkStudent() {} public WorkStudent(String name,int age,String grand) { super(name,age,grand); } public void study() { System.out.println("就业班学员学习的是JavaEE"); } } class AbstractTest3 { public static void main(String[] args) { //我仅仅测试基础班学员 //按照多态的方式测试 Student s = new BasicStudent(); s.setName("林青霞"); s.setAge(27); s.setGrand("1111"); System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getGrand()); s.study(); s.eat(); System.out.println("--------------"); s = new BasicStudent("武鑫",48,"1111"); System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getGrand()); s.study(); s.eat(); } }
D:员工案例练习
/* 假如我们在开发一个系统时需要对员工类进行设计,员工包含3个属性:姓名、工号以及工资。 经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。 请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。 分析: 普通员工类 成员变量:姓名、工号以及工资。 成员方法:工作 经理类: 成员变量:姓名、工号以及工资,奖金属性 成员方法:工作 实现: 员工类: 普通员工类: 经理类: */ //定义员工类 abstract class Employee { //姓名、工号以及工资 private String name; private String id; private int salary; public Employee() {} public Employee(String name,String id,int salary) { this.name = name; this.id = id; this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } //工作 public abstract void work(); } //普通员工类 class Programmer extends Employee { public Programmer(){} public Programmer(String name,String id,int salary) { super(name,id,salary); } public void work() { System.out.println("按照需求写代码"); } } //经理类 class Manager extends Employee { //奖金 private int money; //bonus 奖金 public Manager(){} public Manager(String name,String id,int salary,int money) { super(name,id,salary); this.money = money; } public void work() { System.out.println("跟客户谈需求"); } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } } class AbstractTest4 { public static void main(String[] args) { //测试普通员工 Employee emp = new Programmer(); emp.setName("林青霞"); emp.setId("czbk001"); emp.setSalary(18000); System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary()); emp.work(); System.out.println("-------------"); emp = new Programmer("林青霞","czbk001",18000); System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary()); emp.work(); System.out.println("-------------"); /* emp = new Manager(); emp.setName("刘意"); emp.setId("czbk002"); emp.setSalary(8000); emp.setMoney(2000); */ //由于子类有特有的内容,所以我们用子类来测试 Manager m = new Manager(); m.setName("刘意"); m.setId("czbk002"); m.setSalary(8000); m.setMoney(2000); System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney()); m.work(); System.out.println("-------------"); //通过构造方法赋值 m = new Manager("刘意","czbk002",8000,2000); System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney()); m.work(); }
(5)抽象类的几个小问题
A:抽象类有构造方法,不能实例化,那么构造方法有什么用?
用于子类访问父类数据的初始化
B:一个类如果没有抽象方法,却定义为了抽象类,有什么用?
为了不让创建对象
C:abstract不能和哪些关键字共存
a:final 冲突
b:private 冲突
c:static 无意义
4:接口(掌握)
(1)回顾猫狗案例,它们仅仅提供一些基本功能。
比如:猫钻火圈,狗跳高等功能,不是动物本身就具备的,
是在后面的培养中训练出来的,这种额外的功能,java提供了接口表示。
(2)接口的特点:
A:接口用关键字interface修饰
interface 接口名 {}
B:类实现接口用implements修饰
class 类名 implements 接口名 {}
C:接口不能实例化
D:接口的实现类
a:是一个抽象类。
b:是一个具体类,这个类必须重写接口中的所有抽象方法。
(3)接口的成员特点:
A:成员变量
只能是常量
默认修饰符:public static final
B:构造方法
没有构造方法
C:成员方法
只能是抽象的
默认修饰符:public abstract
(4)类与类,类与接口,接口与接口
A:类与类
继承关系,只能单继承,可以多层继承
B:类与接口
实现关系,可以单实现,也可以多实现。
还可以在继承一个类的同时,实现多个接口
C:接口与接口
继承关系,可以单继承,也可以多继承
(5)抽象类和接口的区别(自己补齐)?
A:成员区别
抽象类:可以常量,可以变量
接口:只能是常量,默认是public static final
B:关系区别:
类与类:单继承,多层继承
类与接口:单实现,多实现
接口与接口:单继承,多继承
C:设计理念不同
抽象类:is a,抽象类中定义的是共性功能。
接口:like a,接口中定义的是扩展功能。
(6)练习:
A:猫狗案例,加入跳高功能
/* 猫狗案例,加入跳高的额外功能 分析:从具体到抽象 猫: 姓名,年龄 吃饭,睡觉 狗: 姓名,年龄 吃饭,睡觉 由于有共性功能,所以,我们抽取出一个父类: 动物: 姓名,年龄 吃饭(); 睡觉(){} 猫:继承自动物 狗:继承自动物 跳高的额外功能是一个新的扩展功能,所以我们要定义一个接口 接口: 跳高 部分猫:实现跳高 部分狗:实现跳高 实现; 从抽象到具体 使用: 使用具体类 */ //定义跳高接口 interface Jumpping { //跳高功能 public abstract void jump(); } //定义抽象类 abstract class Animal { //姓名 private String name; //年龄 private int age; public Animal() {} public Animal(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //吃饭(); public abstract void eat(); //睡觉(){} public void sleep() { System.out.println("睡觉觉了"); } } //具体猫类 class Cat extends Animal { public Cat(){} public Cat(String name,int age) { super(name,age); } public void eat() { System.out.println("猫吃鱼"); } } //具体狗类 class Dog extends Animal { public Dog(){} public Dog(String name,int age) { super(name,age); } public void eat() { System.out.println("狗吃肉"); } } //有跳高功能的猫 class JumpCat extends Cat implements Jumpping { public JumpCat() {} public JumpCat(String name,int age) { super(name,age); } public void jump() { System.out.println("跳高猫"); } } //有跳高功能的狗 class JumpDog extends Dog implements Jumpping { public JumpDog() {} public JumpDog(String name,int age) { super(name,age); } public void jump() { System.out.println("跳高狗"); } } class InterfaceTest { public static void main(String[] args) { //定义跳高猫并测试 JumpCat jc = new JumpCat(); jc.setName("哆啦A梦"); jc.setAge(3); System.out.println(jc.getName()+"---"+jc.getAge()); jc.eat(); jc.sleep(); jc.jump(); System.out.println("-----------------"); JumpCat jc2 = new JumpCat("加菲猫",2); System.out.println(jc2.getName()+"---"+jc2.getAge()); jc2.eat(); jc2.sleep(); jc2.jump(); //定义跳高狗并进行测试的事情自己完成。 } }
B:老师和学生案例,加入抽烟功能0
/* 老师和学生案例,加入抽烟的额外功能 分析:从具体到抽象 老师:姓名,年龄,吃饭,睡觉 学生:姓名,年龄,吃饭,睡觉 由于有共性功能,我们提取出一个父类,人类。 人类: 姓名,年龄 吃饭(); 睡觉(){} 抽烟的额外功能不是人或者老师,或者学生一开始就应该具备的,所以,我们把它定义为接口 抽烟接口。 部分老师抽烟:实现抽烟接口 部分学生抽烟:实现抽烟接口 实现:从抽象到具体 使用:具体 */ //定义抽烟接口 interface Smoking { //抽烟的抽象方法 public abstract void smoke(); } //定义抽象人类 abstract class Person { //姓名 private String name; //年龄 private int age; public Person() {} public Person(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //吃饭(); public abstract void eat(); //睡觉(){} public void sleep() { System.out.println("睡觉觉了"); } } //具体老师类 class Teacher extends Person { public Teacher() {} public Teacher(String name,int age) { super(name,age); } public void eat() { System.out.println("吃大白菜"); } } //具体学生类 class Student extends Person { public Student() {} public Student(String name,int age) { super(name,age); } public void eat() { System.out.println("吃红烧肉"); } } //抽烟的老师 class SmokingTeacher extends Teacher implements Smoking { public SmokingTeacher() {} public SmokingTeacher(String name,int age) { super(name,age); } public void smoke() { System.out.println("抽烟的老师"); } } //抽烟的学生 class SmokingStudent extends Student implements Smoking { public SmokingStudent() {} public SmokingStudent(String name,int age) { super(name,age); } public void smoke() { System.out.println("抽烟的学生"); } } class InterfaceTest2 { public static void main(String[] args) { //测试学生 SmokingStudent ss = new SmokingStudent(); ss.setName("林青霞"); ss.setAge(27); System.out.println(ss.getName()+"---"+ss.getAge()); ss.eat(); ss.sleep(); ss.smoke(); System.out.println("-------------------"); SmokingStudent ss2 = new SmokingStudent("刘意",30); System.out.println(ss2.getName()+"---"+ss2.getAge()); ss2.eat(); ss2.sleep(); ss2.smoke(); //测试老师略 } }
原文地址:https://www.cnblogs.com/zyk2019/p/11372967.html