上海传智播客JAVASE_day09学习笔记
来源:互联网 发布:炭知天下龙泽路手机号 编辑:程序博客网 时间:2024/05/01 19:15
《第九天总结》 张伦琦
《继承、抽象类,接口、多态》
1. 继承
1.1继承中的对象构造顺序
A.自己一句话总结:先父后子,首先是父类的静态的东西经过(静态变量初始化,静态代码块的顺序),
然后再是子类的静态的东西的开始,再者就是父类的成员的东西(成员变量,构造代码块,构造方法)
再是子类的成员的东西。
B.对象的创建过程
1.加载类:处理静态的东西,先父后子
父类静态变量默认初始化
父类静态变量显示初始化
父类静态代码块
子类静态变量默认初始化
子类静态变量显示初始化
子类静态代码块
2.建对象:处理成员的东西,先父后子
父类成员变量默认初始化
父类成员变量显示初始化
父类构造代码块
父类构造函数
子类成员变量默认初始化
子类成员变量显示初始化
子类构造代码块
子类构造函数
C.super()是什么?
代指父类的某个构造方法。(构造方法不能继承,还得用,给起了个名字。)
必须得找到父类构造方法。
D.第一种形式的总结:(理解)
1.除Object类外,所有类都有父类。
2.对象的构造顺序是自上而下的。也就是初始化父类的部分,再初始化子类的部分。
3.所有类的所有构造方法第一句必须是super([x,y,z])
默认方案:构造方法第一句默认隐式调用super();
指定方案:1.构造方法第一句显式调用super([x,y,z])
2.构造方法第一句显式调用this([x,y,z])...>super([x,y,z])
1.2继承中的override
A.自己一句话总结:override,就是重写,就是子类把父类中的同名方法再写一遍!
B.方法重写:override
在子类中重写编写从父类继承下来的方法。
C.方法重载注意:
1.子类方法和父类方法的头部相同。
2.子类覆写父类的方法权限不能小于父类。
D.super和this
super代表子类对象中父类那一部分,可以用来显示调用父类的部分.
E.重载和重写(记忆)
A.Java中的override(重写:动态多态的基础)?
1.子父类中,存在同名方法名
2.同名方法之间的参数列表相同
3.子类方法的返回值 == 父类方法的返回值
4.子类方法的访问权限>=父类方法的访问权限
5.private、static(有人说静态覆盖静态)、final方法均不可重写。
B.Java中的overload(重载:静态多态的基础)?
1.同一类中,存在同名方法
2.同名方法之间的参数列表不同
3.同名方法之间的返回值,没有关系
4.同名方法直接的访问权限,没有关系
5.private、static、final方法均可以重载。
举例
getMax(int i,int j)
getMax(int i,int j,int k)
getMax(int i,int j,int k,int l)
1.3继承中的this和super总结
A.自己一句话总结:this是地址,super是一块内存区域.
1.this代表当前对象,super代表当前对象中存放从父类继承下来的那片内存空间。
2.this可以直接使用,因为它就是对象
3.super不能直接使用,因为它只是一个对象的一个部分。
4.this和super在访问它们各自的成员的时候用法非常相似
5.this()代表本来的某个构造方法,super()代表父类的某个构造方法。
6.除Object类外,所有类的构造方法第一句默认都是super()
无论如何你要保证能找到父类的构造方法。
1.4继承中的final
A.自己一句话总结:final可以修饰类,方法,和数值.被final修饰的类是断子绝孙类,不能被继承了,
只能自己创造对象;被final修饰的方法不能被重写可以被继承,被final修饰的数值
会变成常量。
B.继承好处:
父类的方法和变量能直接被子类继承。并且可以被子类修改
C.继承坏处:
如果父类的方法比较重要,继承可以,但修改不太合适。
你可以将该方法声明为final
final是终态方法,可以被继承,但是不可以被修改。
D.如果类中的所有方法都是final的,干脆类变成final
final class不可以被继承,不能有子类,亦不能有孙类,断子绝孙类
final类中的所有方法都是final的。
E.final变量,变量的值不能被改变。成了常量。
常量的命名规则是 XXX_YYY_ZZZ
有名称的常量的好处是,能一改全改,见名知意。
1.类天生就能被继承,天生可以做父类
2.final类不可以被继承。
F.final总结(记忆)
final变量:变量中的内容不能被改变。(不能被赋值的变量),不能被修改的数据
1.变量的值不能修改。声明常量。
2.常量有名称要大写字母加_
3.static fianl data: 属于类的只有一份的不能改变的常量。
4.值一开始就指定好。在对象构造以前指定好值。
final方法:方法中的内容不能被改变。(不能被重写的方法),不能被修改的方法
1.方法可以继承
2.不能被重写的方法。
final类:类不能被继承。不能被修改的类
2. 抽象类
2.1抽象类的引入
抽象方法的类必须要是抽象类
A.抽象类引子:
动物 跑 吼叫
Dog 跑 吼叫
Wolf 跑 吼叫
class Dog{
public void run(){
System.out.println("狗跑");
}
public void bark(){
System.out.println("狗叫");
}
}
class Wolf{
public void run(){
System.out.println("狼跑");
}
public void bark(){
System.out.println("狼叫");
}
}
B.现在有重复代码 咋办?
弄一个父类Animal,狼和狗还不一样?咋办?
只知道有一个(跑)功能,但不知道这个(跑)功能的具体实现。
abstract方法是 只有方法头没有方法体,叫抽象方法。代码实现不具体。
方法是抽象的,说明方法没有代码,方法不能执行。如果Animal能创建对象
用Animal对象奔跑,岂不是要出事。最好是不跑。对象不能创建。
abstract类,该类不能创建对象。
C.为啥写抽象类?
1.因为编写类的功能信息量不够,Animal不知道具体怎么run()也不知道具体怎么bark()
2.抽象类天生就是当爹的。子孙满堂类。
D.抽象类的注意
1.abstract方法是 只有方法头没有方法体,叫抽象方法。
2.abstract类,该类不能创建对象.
3.抽象方法一定在抽象类中。
4.抽象类中不一定有抽象方法。
5.如果继承下来了抽象方法
a.子类也是抽象类(Dog,Wolf变成抽象类)
b.重写所有的抽象方法。
E.abstract总结:(记住)
1.抽象方法:不能直接运行的方法。(没有方法体)
2.抽象类: 不能实例化对象的类。
3.抽象方法必须在抽象类中。
F.关于抽象类FAQ(理解,面试题)
1.抽象方法必须在抽象类中吗?
是的,抽象方法必须在抽象类中,因为抽象方法只有方法头没有方法体不能执行,不能被对象调用。
那么这个类直接创造对象的条件就不具备,要想防止被对象调用只有让方法所在的类不能产生对象,
只好将方法所在的类声明为抽象类。
2.抽象类中必须有抽象方法吗?
未必,抽象类只是让类不能产生对象。只是说明一个类不具备直接创造对象的条件,这个条件并不一
定和抽象方法相关。适配器可以反驳之。
3.抽象类一定是父类吗?
是的。抽象类不能产生对象,因此它自己不能工作。如果它没有子类,那就是又不让产生子类进行工
作,请问你设计这么一个类还有什么意义呢?
4.子类继承抽象类必须要实现其中的抽象方法吗?
是的,如果子类继承了一个抽象类,那么子类要么全部实现它的所有抽象方法,要么子类也必须是抽
象类。因为抽象方法必须在抽象类中。
5.抽象类不能产生对象,那抽象类中有构造方法吗?
有构造方法,因为抽象类必须是父类。它的子类在创造对象的时候一定会用到父类的构造方法,如果没
有构造方法,子类怎么调用。抽象类本身不能实例化对象,因此它抽象类的构造方法不是用来自己实例
化对象的,而是为其子类实例化对象提供服务的。
6.存在抽象的数据吗?abstact int a=5;
不存在。数据都是具体的,没有抽象的,抽象的数据压根就没有意义。
7.存在私有的抽象的方法吗?
不存在。私有方法是不参与重写的,而抽象方法要求必须进行实现性质的重写。两者矛盾。
private abstract 不能共存
8.存在静态的抽象方法吗?
不存在。静态方法是不参与重写的,而抽象方法要求必须进行实现性质的重写。两者矛盾
static abstract 不能存
9.存在最终的抽象方法吗,存在最终的抽象的类吗?
不存在。最终方法是不参与重写的,而抽象方法要求必须进行实现性质的重写。两者矛盾。
最终类是不参与继承的,而抽象类是必须进行继承。
( 最终的类是断子绝孙的类,抽象的类是子孙满堂的类)两者矛盾。
final abstract 不能共存
2.2抽象类的练习
/*
需求:
程序员有姓名,工号,薪水,项目奖金,工作内容。
业务员有姓名,工号,薪水,业务奖金,工作内容。
对给出需求进行数据建模。
分析:
程序员:
属性:姓名,工号,薪水,项目奖金
方法:工作内容(程序开发)。
业务员:
属性:姓名,工号,薪水,业务奖金
方法:工作内容(程序销售)。
共同的东西:
属性:姓名,工号,薪水
方法:工作内容
代码:
class Programmer{
//属性 姓名,工号,薪水,项目奖金
String name;
String id;
double salary;
double projectBonus;
//方法 工作内容(程序开发)。
public void work(){
System.out.println("程序开发");
}
}
class Saler{
//属性 姓名,工号,薪水,业务奖金
String name;
String id;
double salary;
double saleBonus;
//方法 工作内容(程序销售)。
public void work(){
System.out.println("程序销售");
}
}
现在可以运行,但是有代码重复。
*/
abstract class Clerk{
//属性:姓名,工号,薪水
private String name;
private String id;
double salary;
public Clerk(){
//抽象类中可以有抽象方法,为子类构建对象做准备。
}
public Clerk(String name,String id,double salary){
this.name=name;
this.id=id;
this.salary=salary;
}
//方法:工作内容,获取收入
public abstract void work();
public abstract double getMoney();
public void show(){
System.out.println("name="+name+",id="+id+"salary"+salary);
}
}
class Programmer extends Clerk{
//属性:项目奖金
private double projectBonus;
public Programmer(){
super();//默认
}
public Programmer(String name,String id,double salary,double projectBonus){
super(name, id, salary);//调用父类构造方法,来初始化变量
this.projectBonus=projectBonus;
}
//方法:重写,工作内容(程序开发)。
public void work(){
System.out.println("程序开发");
}
public double getMoney(){
//this.salary找不到,私有要去掉
//this.salary找不到,私有要去掉
return super.salary+this.projectBonus;
}
}
class Saler extends Clerk{
//属性:业务奖金
private double saleBonus;
public Saler(){
super();//默认
}
public Saler(String name,String id,double salary,double saleBonus){
super(name, id, salary);//调用父类构造方法,来初始化变量
this.saleBonus=saleBonus;
}
//方法:重写,工作内容(程序销售)。
public void work(){
System.out.println("程序销售");
}
public double getMoney(){
return this.salary+this.saleBonus;
}
}
//测试类
class AbstractTest {
public static void main(String[] args) {
Programmer p=new Programmer("张三","bd001",8000.23,12000.25);
p.work();
double money=p.getMoney();
System.out.println(money);
Saler s=new Saler("李四","bd002",4000.23,52000.25);
s.work();
money=s.getMoney();
System.out.println(money);
s.show();
p.show();
}
}
3. 接口
3.1接口引入
A.自己的一句话总结:interface修饰,里面的方法全部是public abstract的,里面的数值全部是public static final的,
使用接口必须使用里面的所有东西。
B.接口引入的例子
面向接口编程
访问接口:getter和setter
如果出来这个全部抽象方法的类?
abstract class Animal{
public abstract void eat();
public abstract void sleep();
public abstract void run();
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
public void sleep(){
System.out.println("狗天天睡");
}
public void run(){
System.out.println("人模狗样");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void sleep(){
System.out.println("猫白天睡");
}
public void run(){
System.out.println("人模猫样");
}
}
动物中所有的方法都是抽象的。
interface接口:
1.接口中的方法全是抽象的。
2.接口中的方法全是public的
C.接口的特点(理解)
1.接口中方法全部都是 public abstract 的。
2.接口中变量全部都是 public static final 的。
(接口中的数据都是不可变的,接口中的方法都是可改变的)
3.接口中没有构造方法,不能创建对象。
4.接口中的所有抽象方法必须在实现类中实现,否则实现类也必须是抽象的。
D.接口的FAQ(理解)
接口中都是抽象的。
1.接口可以实现(implements)接口吗?
不能,接口中没有可以直接运行的代码,也就是没有具体的实现(implements),因此它不能实现接口。
2.接口可以继承类或者抽象类吗?
不能,接口中不能有任何具体的实现。普通类不行,抽象类也不行。因为抽象类可能有具体的实现。
3.接口可以继承接口吗?
可以,接口中没有具体的实现,继承下来不会产生冲突。
4.一个接口可以继承多个接口吗?
可以,
5.一个类可以实现(implements)多个接口吗?
可以
6.一个类实现(implements)接口和继承类能共存吗?
可以
E.两道面试题(理解)
面试题1:java中有多继承吗?
在类的继承体系中,存在着单根继承,多层继承。
在接口的继承体系中,存在这多根继承,多层继承。
面试题2:为什么类不能多继承,而接口可以多继承。
因为类中的方法有可能不是抽象的,如果允许多继承就会出现调用的不确定性。可能出现菱形问题。
因为接口中的方法都是抽象的,即使允许多重继承,也不会出现调用的不确定性。不会出现菱形问题。
F.继承体系中的三种关系(理解)
1.子类与父类的关系
继承关系,extends表示,is-a关系,单重继承,多层继承.
2.实现类与接口的关系
实现关系,implements表示,like-a关系,多重实现,多层实现。
3.子接口与父接口的关系
继承关系,extends表示,多重继承,多层继承。
G.接口的一些特点(理解)
接口是一种契约规范合同。
接口是对外暴露的规则。
接口是程序的功能扩展。
接口的出现降低耦合性。(暂时没学)
接口可以用来多实现。
类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
接口与接口之间可以有多继承关系。
H.抽象类和接口的关系(记忆)
相同点:都是不断抽取出来的抽象的概念,都不能创建对象。
必须是由子类或实现类来创建对象。子类必须实现所有抽象方法。
不同点:
A:内部成员不同
抽象类:
构造方法:有构造,初始化子类对象使用
成员方法:有抽象的,有非抽象的
成员变量:有常量,有变量
接口:
构造方法:无。初始子类需要父类构造方法,不需要接口的构造方法,
因此没必要提供。
成员方法:只能是抽象的。默认修饰符:public abstract
成员变量:只能是常量。 默认修饰符:public static final
B:继承表现不同:
抽象类:
一个类只能继承一个抽象类。只能有一个爹
接口:
一个类可以多实现多个接口。可以有多个大爷
一个接口可以继承多个接口。接口可以有多个爹
C:关系本质不同
抽象类被继承表示的是:"is a" 的关系,extends关键字
接口被实现表示的是:"like a" 的关系,implements关键字
D:实质含义不同:(看情况)
抽象类在继承体系中体现着子类的共有功能。
接口在继承体系中体系着实现类的扩展功能。
E.为啥接口比抽象类好?(扩展)
增加抽象类可能会改变原有继承体系,如果增加接口,则不会改变原有继承体系。
I.使用接口的例子
interface Animal{
/* Animal(){
//自己不能创建对象。用不到
//子类型构造对象的时候也用不到。
}
*/
public static final int age=10;
public abstract void eat();//有静态吗?没有
public abstract void sleep();
public abstract void run();
}
//implements实现 Dog类是Animal接口的实现类
class Dog extends Object implements Animal{
Dog(){
super();
}
public void eat(){
System.out.println("狗吃骨头");
}
public void sleep(){
System.out.println("狗天天睡");
}
public void run(){
System.out.println("人模狗样");
}
}
class Cat implements Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void sleep(){
System.out.println("猫白天睡");
}
public void run(){
System.out.println("人模猫样");
}
}
class InterFaceDemo {
public static void main(String[] args) {
Dog d=new Dog();
d.eat();
d.run();
d.sleep();
Cat c=new Cat();
c.eat();
c.run();
c.sleep();
}
}
3.2适配器模式
/*
interface Inter{
public abstract void show1();
public abstract void show2();
public abstract void show3();
public abstract void show4();
}
class InterImpl1 implements Inter{
public void show1(){
//第一实现类只知道,第一show1()的具体实现
System.out.println("InterImpl1--> show1()");
}
public void show2(){}//空实现
public void show3(){}
public void show4(){}
}
class InterImpl2 implements Inter{
public void show1(){}//空实现
public void show2(){}
public void show3(){
//第二个实现类只知道,show3()这个方法的具体实现
System.out.println("InterImpl2--> show3()");
}
public void show4(){}
}
存在大量重复代码怎么办?
如果接口中有四十个抽象方法,难道没一个实现类都要实现四十个方法吗?
为啥有大量的空实现。因为实现类中存在大量的抽象方法,必须要全部实现。
如果没有抽象方法,就不需要空实现了。
怎么能保证没有抽象方法呢?
*/
//适配器模式,用一个类去实现接口的所有方法,其他类作为适配器的子类。
interface Inter{
public abstract void show1();
public abstract void show2();
public abstract void show3();
public abstract void show4();
}
//适配器,抽象类中可以没有抽象方法,抽象类的本质是不让类创建对象。
abstract class Adapter implements Inter{
/*
此处不可以用私有构造方法实现,只能将类变为抽象类
private Adapter(){
}
*/
//一个类实现接口中全部的方法,而且全部是空实现
public void show1(){}
public void show2(){}
public void show3(){}
public void show4(){}
}
//原来实现接口的类,改变成Adapter类的子类
class InterImpl1 extends Adapter{
/*
辅助分析为什么只能是抽象类,不能是私有构造方法
InterImpl1(){
super();
}
*/
public void show1(){
//第一实现类只知道,第一show1()的具体实现
System.out.println("InterImpl1--> show1()");
}
}
class InterImpl2 extends Adapter{
public void show3(){
//第二个实现类只知道,show3()这个方法的具体实现
System.out.println("InterImpl2--> show3()");
}
}
class AdapterDemo {
public static void main(String[] args) {
InterImpl1 i1=new InterImpl1();
i1.show2();
/*无意义,压根就不让你创建Adapter的对象
Adapter a=new Adapter();
a.show1();
a.show2();
a.show3();
a.show4();
*/
}
}
4. 关键字总结和访问修饰符
private
1.私有变量:该变量只能在本类中使用。
2.私有方法:该方法只能在本类中使用。
abstract
1.抽象类,不能创建对象的类。
2.抽象方法,没有方法体的方法。
static (对象能找到它,它找不到对象)
1.静态方法:和类相关的方法。
2.静态变量:和类相关的变量。
final
1.final 变量 :变量的值不能修改,常量。
2.final 方法 : 方法不能被修改(可以继承,不能重写)
3.final 类 : 类不能被修改(不能被继承)
四种最大访问权限
包外可以访问 public
包子类外可以访问 protected
包内可以访问 不写(default不是关键字,不写)
类内可以访问 private
《继承、抽象类,接口、多态》
1. 继承
1.1继承中的对象构造顺序
A.自己一句话总结:先父后子,首先是父类的静态的东西经过(静态变量初始化,静态代码块的顺序),
然后再是子类的静态的东西的开始,再者就是父类的成员的东西(成员变量,构造代码块,构造方法)
再是子类的成员的东西。
B.对象的创建过程
1.加载类:处理静态的东西,先父后子
父类静态变量默认初始化
父类静态变量显示初始化
父类静态代码块
子类静态变量默认初始化
子类静态变量显示初始化
子类静态代码块
2.建对象:处理成员的东西,先父后子
父类成员变量默认初始化
父类成员变量显示初始化
父类构造代码块
父类构造函数
子类成员变量默认初始化
子类成员变量显示初始化
子类构造代码块
子类构造函数
C.super()是什么?
代指父类的某个构造方法。(构造方法不能继承,还得用,给起了个名字。)
必须得找到父类构造方法。
D.第一种形式的总结:(理解)
1.除Object类外,所有类都有父类。
2.对象的构造顺序是自上而下的。也就是初始化父类的部分,再初始化子类的部分。
3.所有类的所有构造方法第一句必须是super([x,y,z])
默认方案:构造方法第一句默认隐式调用super();
指定方案:1.构造方法第一句显式调用super([x,y,z])
2.构造方法第一句显式调用this([x,y,z])...>super([x,y,z])
1.2继承中的override
A.自己一句话总结:override,就是重写,就是子类把父类中的同名方法再写一遍!
B.方法重写:override
在子类中重写编写从父类继承下来的方法。
C.方法重载注意:
1.子类方法和父类方法的头部相同。
2.子类覆写父类的方法权限不能小于父类。
D.super和this
super代表子类对象中父类那一部分,可以用来显示调用父类的部分.
E.重载和重写(记忆)
A.Java中的override(重写:动态多态的基础)?
1.子父类中,存在同名方法名
2.同名方法之间的参数列表相同
3.子类方法的返回值 == 父类方法的返回值
4.子类方法的访问权限>=父类方法的访问权限
5.private、static(有人说静态覆盖静态)、final方法均不可重写。
B.Java中的overload(重载:静态多态的基础)?
1.同一类中,存在同名方法
2.同名方法之间的参数列表不同
3.同名方法之间的返回值,没有关系
4.同名方法直接的访问权限,没有关系
5.private、static、final方法均可以重载。
举例
getMax(int i,int j)
getMax(int i,int j,int k)
getMax(int i,int j,int k,int l)
1.3继承中的this和super总结
A.自己一句话总结:this是地址,super是一块内存区域.
1.this代表当前对象,super代表当前对象中存放从父类继承下来的那片内存空间。
2.this可以直接使用,因为它就是对象
3.super不能直接使用,因为它只是一个对象的一个部分。
4.this和super在访问它们各自的成员的时候用法非常相似
5.this()代表本来的某个构造方法,super()代表父类的某个构造方法。
6.除Object类外,所有类的构造方法第一句默认都是super()
无论如何你要保证能找到父类的构造方法。
1.4继承中的final
A.自己一句话总结:final可以修饰类,方法,和数值.被final修饰的类是断子绝孙类,不能被继承了,
只能自己创造对象;被final修饰的方法不能被重写可以被继承,被final修饰的数值
会变成常量。
B.继承好处:
父类的方法和变量能直接被子类继承。并且可以被子类修改
C.继承坏处:
如果父类的方法比较重要,继承可以,但修改不太合适。
你可以将该方法声明为final
final是终态方法,可以被继承,但是不可以被修改。
D.如果类中的所有方法都是final的,干脆类变成final
final class不可以被继承,不能有子类,亦不能有孙类,断子绝孙类
final类中的所有方法都是final的。
E.final变量,变量的值不能被改变。成了常量。
常量的命名规则是 XXX_YYY_ZZZ
有名称的常量的好处是,能一改全改,见名知意。
1.类天生就能被继承,天生可以做父类
2.final类不可以被继承。
F.final总结(记忆)
final变量:变量中的内容不能被改变。(不能被赋值的变量),不能被修改的数据
1.变量的值不能修改。声明常量。
2.常量有名称要大写字母加_
3.static fianl data: 属于类的只有一份的不能改变的常量。
4.值一开始就指定好。在对象构造以前指定好值。
final方法:方法中的内容不能被改变。(不能被重写的方法),不能被修改的方法
1.方法可以继承
2.不能被重写的方法。
final类:类不能被继承。不能被修改的类
2. 抽象类
2.1抽象类的引入
自己的一句话总结:
抽象abstract可以修饰类,方法,修饰类是代表这个抽象类是天生爸爸类,不能直接创造对象
天生就是给其他类继承的;抽象方法时,代表这个类没有方法体,就是给其他类重写的,但是有抽象方法的类必须要是抽象类
A.抽象类引子:
动物 跑 吼叫
Dog 跑 吼叫
Wolf 跑 吼叫
class Dog{
public void run(){
System.out.println("狗跑");
}
public void bark(){
System.out.println("狗叫");
}
}
class Wolf{
public void run(){
System.out.println("狼跑");
}
public void bark(){
System.out.println("狼叫");
}
}
B.现在有重复代码 咋办?
弄一个父类Animal,狼和狗还不一样?咋办?
只知道有一个(跑)功能,但不知道这个(跑)功能的具体实现。
abstract方法是 只有方法头没有方法体,叫抽象方法。代码实现不具体。
方法是抽象的,说明方法没有代码,方法不能执行。如果Animal能创建对象
用Animal对象奔跑,岂不是要出事。最好是不跑。对象不能创建。
abstract类,该类不能创建对象。
C.为啥写抽象类?
1.因为编写类的功能信息量不够,Animal不知道具体怎么run()也不知道具体怎么bark()
2.抽象类天生就是当爹的。子孙满堂类。
D.抽象类的注意
1.abstract方法是 只有方法头没有方法体,叫抽象方法。
2.abstract类,该类不能创建对象.
3.抽象方法一定在抽象类中。
4.抽象类中不一定有抽象方法。
5.如果继承下来了抽象方法
a.子类也是抽象类(Dog,Wolf变成抽象类)
b.重写所有的抽象方法。
E.abstract总结:(记住)
1.抽象方法:不能直接运行的方法。(没有方法体)
2.抽象类: 不能实例化对象的类。
3.抽象方法必须在抽象类中。
F.关于抽象类FAQ(理解,面试题)
1.抽象方法必须在抽象类中吗?
是的,抽象方法必须在抽象类中,因为抽象方法只有方法头没有方法体不能执行,不能被对象调用。
那么这个类直接创造对象的条件就不具备,要想防止被对象调用只有让方法所在的类不能产生对象,
只好将方法所在的类声明为抽象类。
2.抽象类中必须有抽象方法吗?
未必,抽象类只是让类不能产生对象。只是说明一个类不具备直接创造对象的条件,这个条件并不一
定和抽象方法相关。适配器可以反驳之。
3.抽象类一定是父类吗?
是的。抽象类不能产生对象,因此它自己不能工作。如果它没有子类,那就是又不让产生子类进行工
作,请问你设计这么一个类还有什么意义呢?
4.子类继承抽象类必须要实现其中的抽象方法吗?
是的,如果子类继承了一个抽象类,那么子类要么全部实现它的所有抽象方法,要么子类也必须是抽
象类。因为抽象方法必须在抽象类中。
5.抽象类不能产生对象,那抽象类中有构造方法吗?
有构造方法,因为抽象类必须是父类。它的子类在创造对象的时候一定会用到父类的构造方法,如果没
有构造方法,子类怎么调用。抽象类本身不能实例化对象,因此它抽象类的构造方法不是用来自己实例
化对象的,而是为其子类实例化对象提供服务的。
6.存在抽象的数据吗?abstact int a=5;
不存在。数据都是具体的,没有抽象的,抽象的数据压根就没有意义。
7.存在私有的抽象的方法吗?
不存在。私有方法是不参与重写的,而抽象方法要求必须进行实现性质的重写。两者矛盾。
private abstract 不能共存
8.存在静态的抽象方法吗?
不存在。静态方法是不参与重写的,而抽象方法要求必须进行实现性质的重写。两者矛盾
static abstract 不能存
9.存在最终的抽象方法吗,存在最终的抽象的类吗?
不存在。最终方法是不参与重写的,而抽象方法要求必须进行实现性质的重写。两者矛盾。
最终类是不参与继承的,而抽象类是必须进行继承。
( 最终的类是断子绝孙的类,抽象的类是子孙满堂的类)两者矛盾。
final abstract 不能共存
2.2抽象类的练习
/*
需求:
程序员有姓名,工号,薪水,项目奖金,工作内容。
业务员有姓名,工号,薪水,业务奖金,工作内容。
对给出需求进行数据建模。
分析:
程序员:
属性:姓名,工号,薪水,项目奖金
方法:工作内容(程序开发)。
业务员:
属性:姓名,工号,薪水,业务奖金
方法:工作内容(程序销售)。
共同的东西:
属性:姓名,工号,薪水
方法:工作内容
代码:
class Programmer{
//属性 姓名,工号,薪水,项目奖金
String name;
String id;
double salary;
double projectBonus;
//方法 工作内容(程序开发)。
public void work(){
System.out.println("程序开发");
}
}
class Saler{
//属性 姓名,工号,薪水,业务奖金
String name;
String id;
double salary;
double saleBonus;
//方法 工作内容(程序销售)。
public void work(){
System.out.println("程序销售");
}
}
现在可以运行,但是有代码重复。
*/
abstract class Clerk{
//属性:姓名,工号,薪水
private String name;
private String id;
double salary;
public Clerk(){
//抽象类中可以有抽象方法,为子类构建对象做准备。
}
public Clerk(String name,String id,double salary){
this.name=name;
this.id=id;
this.salary=salary;
}
//方法:工作内容,获取收入
public abstract void work();
public abstract double getMoney();
public void show(){
System.out.println("name="+name+",id="+id+"salary"+salary);
}
}
class Programmer extends Clerk{
//属性:项目奖金
private double projectBonus;
public Programmer(){
super();//默认
}
public Programmer(String name,String id,double salary,double projectBonus){
super(name, id, salary);//调用父类构造方法,来初始化变量
this.projectBonus=projectBonus;
}
//方法:重写,工作内容(程序开发)。
public void work(){
System.out.println("程序开发");
}
public double getMoney(){
//this.salary找不到,私有要去掉
//this.salary找不到,私有要去掉
return super.salary+this.projectBonus;
}
}
class Saler extends Clerk{
//属性:业务奖金
private double saleBonus;
public Saler(){
super();//默认
}
public Saler(String name,String id,double salary,double saleBonus){
super(name, id, salary);//调用父类构造方法,来初始化变量
this.saleBonus=saleBonus;
}
//方法:重写,工作内容(程序销售)。
public void work(){
System.out.println("程序销售");
}
public double getMoney(){
return this.salary+this.saleBonus;
}
}
//测试类
class AbstractTest {
public static void main(String[] args) {
Programmer p=new Programmer("张三","bd001",8000.23,12000.25);
p.work();
double money=p.getMoney();
System.out.println(money);
Saler s=new Saler("李四","bd002",4000.23,52000.25);
s.work();
money=s.getMoney();
System.out.println(money);
s.show();
p.show();
}
}
3. 接口
3.1接口引入
A.自己的一句话总结:interface修饰,里面的方法全部是public abstract的,里面的数值全部是public static final的,
使用接口必须使用里面的所有东西。
B.接口引入的例子
面向接口编程
访问接口:getter和setter
如果出来这个全部抽象方法的类?
abstract class Animal{
public abstract void eat();
public abstract void sleep();
public abstract void run();
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
public void sleep(){
System.out.println("狗天天睡");
}
public void run(){
System.out.println("人模狗样");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void sleep(){
System.out.println("猫白天睡");
}
public void run(){
System.out.println("人模猫样");
}
}
动物中所有的方法都是抽象的。
interface接口:
1.接口中的方法全是抽象的。
2.接口中的方法全是public的
C.接口的特点(理解)
1.接口中方法全部都是 public abstract 的。
2.接口中变量全部都是 public static final 的。
(接口中的数据都是不可变的,接口中的方法都是可改变的)
3.接口中没有构造方法,不能创建对象。
4.接口中的所有抽象方法必须在实现类中实现,否则实现类也必须是抽象的。
D.接口的FAQ(理解)
接口中都是抽象的。
1.接口可以实现(implements)接口吗?
不能,接口中没有可以直接运行的代码,也就是没有具体的实现(implements),因此它不能实现接口。
2.接口可以继承类或者抽象类吗?
不能,接口中不能有任何具体的实现。普通类不行,抽象类也不行。因为抽象类可能有具体的实现。
3.接口可以继承接口吗?
可以,接口中没有具体的实现,继承下来不会产生冲突。
4.一个接口可以继承多个接口吗?
可以,
5.一个类可以实现(implements)多个接口吗?
可以
6.一个类实现(implements)接口和继承类能共存吗?
可以
E.两道面试题(理解)
面试题1:java中有多继承吗?
在类的继承体系中,存在着单根继承,多层继承。
在接口的继承体系中,存在这多根继承,多层继承。
面试题2:为什么类不能多继承,而接口可以多继承。
因为类中的方法有可能不是抽象的,如果允许多继承就会出现调用的不确定性。可能出现菱形问题。
因为接口中的方法都是抽象的,即使允许多重继承,也不会出现调用的不确定性。不会出现菱形问题。
F.继承体系中的三种关系(理解)
1.子类与父类的关系
继承关系,extends表示,is-a关系,单重继承,多层继承.
2.实现类与接口的关系
实现关系,implements表示,like-a关系,多重实现,多层实现。
3.子接口与父接口的关系
继承关系,extends表示,多重继承,多层继承。
G.接口的一些特点(理解)
接口是一种契约规范合同。
接口是对外暴露的规则。
接口是程序的功能扩展。
接口的出现降低耦合性。(暂时没学)
接口可以用来多实现。
类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
接口与接口之间可以有多继承关系。
H.抽象类和接口的关系(记忆)
相同点:都是不断抽取出来的抽象的概念,都不能创建对象。
必须是由子类或实现类来创建对象。子类必须实现所有抽象方法。
不同点:
A:内部成员不同
抽象类:
构造方法:有构造,初始化子类对象使用
成员方法:有抽象的,有非抽象的
成员变量:有常量,有变量
接口:
构造方法:无。初始子类需要父类构造方法,不需要接口的构造方法,
因此没必要提供。
成员方法:只能是抽象的。默认修饰符:public abstract
成员变量:只能是常量。 默认修饰符:public static final
B:继承表现不同:
抽象类:
一个类只能继承一个抽象类。只能有一个爹
接口:
一个类可以多实现多个接口。可以有多个大爷
一个接口可以继承多个接口。接口可以有多个爹
C:关系本质不同
抽象类被继承表示的是:"is a" 的关系,extends关键字
接口被实现表示的是:"like a" 的关系,implements关键字
D:实质含义不同:(看情况)
抽象类在继承体系中体现着子类的共有功能。
接口在继承体系中体系着实现类的扩展功能。
E.为啥接口比抽象类好?(扩展)
增加抽象类可能会改变原有继承体系,如果增加接口,则不会改变原有继承体系。
I.使用接口的例子
interface Animal{
/* Animal(){
//自己不能创建对象。用不到
//子类型构造对象的时候也用不到。
}
*/
public static final int age=10;
public abstract void eat();//有静态吗?没有
public abstract void sleep();
public abstract void run();
}
//implements实现 Dog类是Animal接口的实现类
class Dog extends Object implements Animal{
Dog(){
super();
}
public void eat(){
System.out.println("狗吃骨头");
}
public void sleep(){
System.out.println("狗天天睡");
}
public void run(){
System.out.println("人模狗样");
}
}
class Cat implements Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void sleep(){
System.out.println("猫白天睡");
}
public void run(){
System.out.println("人模猫样");
}
}
class InterFaceDemo {
public static void main(String[] args) {
Dog d=new Dog();
d.eat();
d.run();
d.sleep();
Cat c=new Cat();
c.eat();
c.run();
c.sleep();
}
}
3.2适配器模式
/*
interface Inter{
public abstract void show1();
public abstract void show2();
public abstract void show3();
public abstract void show4();
}
class InterImpl1 implements Inter{
public void show1(){
//第一实现类只知道,第一show1()的具体实现
System.out.println("InterImpl1--> show1()");
}
public void show2(){}//空实现
public void show3(){}
public void show4(){}
}
class InterImpl2 implements Inter{
public void show1(){}//空实现
public void show2(){}
public void show3(){
//第二个实现类只知道,show3()这个方法的具体实现
System.out.println("InterImpl2--> show3()");
}
public void show4(){}
}
存在大量重复代码怎么办?
如果接口中有四十个抽象方法,难道没一个实现类都要实现四十个方法吗?
为啥有大量的空实现。因为实现类中存在大量的抽象方法,必须要全部实现。
如果没有抽象方法,就不需要空实现了。
怎么能保证没有抽象方法呢?
*/
//适配器模式,用一个类去实现接口的所有方法,其他类作为适配器的子类。
interface Inter{
public abstract void show1();
public abstract void show2();
public abstract void show3();
public abstract void show4();
}
//适配器,抽象类中可以没有抽象方法,抽象类的本质是不让类创建对象。
abstract class Adapter implements Inter{
/*
此处不可以用私有构造方法实现,只能将类变为抽象类
private Adapter(){
}
*/
//一个类实现接口中全部的方法,而且全部是空实现
public void show1(){}
public void show2(){}
public void show3(){}
public void show4(){}
}
//原来实现接口的类,改变成Adapter类的子类
class InterImpl1 extends Adapter{
/*
辅助分析为什么只能是抽象类,不能是私有构造方法
InterImpl1(){
super();
}
*/
public void show1(){
//第一实现类只知道,第一show1()的具体实现
System.out.println("InterImpl1--> show1()");
}
}
class InterImpl2 extends Adapter{
public void show3(){
//第二个实现类只知道,show3()这个方法的具体实现
System.out.println("InterImpl2--> show3()");
}
}
class AdapterDemo {
public static void main(String[] args) {
InterImpl1 i1=new InterImpl1();
i1.show2();
/*无意义,压根就不让你创建Adapter的对象
Adapter a=new Adapter();
a.show1();
a.show2();
a.show3();
a.show4();
*/
}
}
4. 关键字总结和访问修饰符
private
1.私有变量:该变量只能在本类中使用。
2.私有方法:该方法只能在本类中使用。
abstract
1.抽象类,不能创建对象的类。
2.抽象方法,没有方法体的方法。
static (对象能找到它,它找不到对象)
1.静态方法:和类相关的方法。
2.静态变量:和类相关的变量。
final
1.final 变量 :变量的值不能修改,常量。
2.final 方法 : 方法不能被修改(可以继承,不能重写)
3.final 类 : 类不能被修改(不能被继承)
四种最大访问权限
包外可以访问 public
包子类外可以访问 protected
包内可以访问 不写(default不是关键字,不写)
类内可以访问 private
0 0
- 上海传智播客JAVASE_day09学习笔记
- JavaSe_day09
- 上海传智播客JAVASE_day01学习笔记
- 上海传智播客JAVASE_day02学习笔记
- 上海传智播客JAVASE_day03学习笔记
- 上海传智播客JAVASE_day04学习笔记
- 上海传智播客JAVASE_day05学习笔记
- 上海传智播客JAVASE_day06学习笔记
- 上海传智播客JAVASE_day07学习笔记
- 上海传智播客JAVASE_day08学习笔记
- 上海传智播客JAVASE_day10学习笔记
- 上海传智播客JAVASE_day11学习笔记
- 上海传智播客JAVASE_day12学习笔记
- 上海传智播客JAVASE_day13学习笔记
- 上海传智播客JAVASE_day14学习笔记
- 上海传智播客JAVASE_day15学习笔记
- 上海传智播客JAVASE_day16学习笔记
- 上海传智播客JAVASE_day17学习笔记
- Linux常用命令之-压缩解压缩
- 我为什么写博客
- Dividing hdu acm 1059 c++
- oracle 笔记 游标
- C++中如何根据多个字节读取二进制文件
- 上海传智播客JAVASE_day09学习笔记
- Qt浅谈之十六:TCP和UDP(之二)
- 用到哪学到哪------Thinkphp ajaxReturn的数据类型
- PL/SQL编程基础
- 字符串的排列
- 12,activity 屏幕触摸汇总
- WinForm自定义弹出框边角圆滑处理
- 吴大全案
- CH Round #49 - Streaming #4 (NOIP模拟赛Day2)