概要图

一, 继承的进阶

1.1,成员变量

重点明确原理。
特殊情况:
子父类中定义了一模一样的成员变量。
都存在于子类对象中。
如何在子类中直接访问同名的父类中的变量呢?
通过关键字 super来完成。

super和this的用法很相似。
this:代表的是本类的对象的引用。
super:代表的是父类的内存空间。

注意:这种情况开发见不到,因为父类一旦描述完了属性,子类直接使用就可以了。

//父类。
class Fu
{
/*private int num1 = 3;*///父类中私有的内容子类不可以直接访问。
int num = ;
} class Zi extends Fu
{
/*int num2 = 4;*/
int num = ;
void show()
{
// System.out.println("num1="+num1);
// System.out.println("num2="+num2); System.out.println("zi num="+num); // num=4
System.out.println("fu num="+super.num);// num=3 }
} class ExtendsDemo
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
}
}

图解

1.2 成员函数@@

子父类中成员函数的特点

特殊情况:
子父类中的定义了一模一样的函数
运行的结果:子类的函数在运行
这种情况在子父类中,是函数的另一个特性:override(重写,覆盖,复写)

【重写什么时候用?】
举例:
//描述手机。

class Phone
{
int number;
//打电话。
void call(){}
//来电显示。
void show()
{
sop("电话号码.."+number);
}
}
Phone p = new Phone();
p.show();

随着电话的升级,只显示号码不爽,希望显示姓名,大头贴。
修改源码,虽然费劲但是可以解决,不利于后期的维护和扩展。
为了扩展方便。新功能是不是新的电话具备呢?
单独描述单独封装。新电话也是电话中的一种。继承。直接获取父类中的功能。
但是新电话的来显功能已经变化了。需要重新定义。
那么定义一个新功能合适吗?比如newShow,不合适,因为父类已经将来显功能定义完了,
子类完全不需要重新定义新功能。直接用就可以了。如果子类的来显功能内容不同。
直需要保留来显功能,定义子类的内容即可:这就是重写的应用!

class NewPhone extends Phone
{
String name;
String picPath;//图片路径。
void show()
{
//sop("电话号码");
super.show();//如果还需要父类中原有的部分功能,可以通过super调用。@@@@@
sop("姓名"+name);
sop("大头贴"+picPath);
}
}

【重写(覆盖)的注意事项】@@

1,子类覆盖父类,必须保证全要大于或者等于父类的权限。
Fu:
private void show(){}

Zi:
public void show(){}
2,静态覆盖静态。

写法上稍微注意:必须一模一样:函数的返回值类型 , 函数名 参数列表都要一样

【重写总结】
当一个类是另一个类中的一种时,可以通过继承,来扩展功能。
如果从父类具备的功能内容需要子类特殊定义时,使用重写。

*/

class Fu
{
int show()
{
System.out.println("fu show run");
return ;
}
}
class Zi extends Fu
{
void show()
{
System.out.println("zi show run");
}
}
class ExtendsDemo2
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
}
}

 图解

1.3 构造函数

【子父类中构造函数的特点】

class Fu
{
int Fu()
{
System.out.println("fu show run");
return ;
}
}
class Zi extends Fu
{
void Zi()
{
System.out.println("zi show run");
}
}
class ExtendsDemo2
{
public static void main(String[] args)
{
new Zi();
}
}

当子父类都有构造函数时,发现结果为:
fu constructor run
zi constructor run
先执行了父类的构造函数,再执行子类的构造函数。

【这是为啥呢?】
因为子类的所有的构造函数中的第一行都有一句隐式语句 super(); //默认调用的是父类中的空参数的构造函数。

【子类中的构造函数为什么有一句隐式的super()呢?】
原因:子类会继承父类中的内容,所以子类在初始化时,必须先到父类中去执行父类的初始化动作。
才可以更方便的使用父类中的内容。

【小结】
当父类中没有空参数构造函数时,子类的构造函数必须同构显示的super语句指定要访问的父类中的构造函数。
这就是传说中的子类实例化过程。*/

class Fu
{ Fu()
{
//super();
//显示初始化。
System.out.println("fu constructor run..A..");
}
Fu(int x)
{
//显示初始化。
System.out.println("fu constructor run..B.."+x);
}
}
class Zi extends Fu
{
Zi()
{ System.out.println("zi constructor run..C..");
}
Zi(int x)
{ System.out.println("zi constructor run..D.."+x);
}
}
class ExtendsDemo3
{
public static void main(String[] args)
{
// new Zi(); // AC@@
new Zi(); // AD@@
}
}

【实例化过程的细节】
1,如果子类的构造函数第一行写了this调用了本类其他构造函数,那么super调用父类的语句还有吗?
没有的因为this()或者super(),只能定义在构造函数的第一行,因为初始化动作要先执行

2,父类构造函数中是否有隐式的super呢?
也是有的。记住:只要是构造函数默认第一行都是super();
父类的父类是谁呢?super调用的到底是谁的构造函数呢?
Java体系在设计,定义了一个所有对象的父类Object ,

【总结】
类中的构造函数默认第一行都有隐式的super()语句,在访问父类中的构造函数。
所以父类的构造函数既可以给自己的对象初始化,也可以给自己的子类对象初始化。

如果默认的隐式super语句没有对应的构造函数,必须在构造函数中通过this或者super的形式明确调用的构造函数。

【问题】@@@
1,this语句和super语句是否可以在同一个构造函数中出现呢?不行,因为必须定义在第一行。
2,为什么要定义在第一行呢?因为初始化动作要先执行。

//子类的实例化过程的应用。也是super调用的应用
//什么时候用super调用父类中构造函数。只要使用父类的指定初始化动作,就在子类中通过super(参数列表)格式进行调用。

class Person
{
private String name;
private int age;
public Person(String name,int age)
{
this.name = name;
this.age = age;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return age;
}
} class Student extends Person
{
public Student(String name,int age)
{ //调用父类。使用父类的初始化动作。
super(name,age);
}
public void study()
{}
} class Worker extends Person
{
public Worker(String name,int age)
{
//调用父类。使用父类的初始化动作。
super(name,age);
}
}

1.4  final

可以修饰 类,方法,变量  

/*
继承的弊端:打破封装性。
不让其他类继承该类,就不会有重写。
怎么能实现呢?通过Java中的一个关键字来实现,final(最终化)。

【final关键字】
是一个修饰符,可以修饰类,方法,变量(成员变量,局部变量,静态变量)。
【特点】
1,final修饰的类是一个最终类,不能在派生子类。
如果类中从出现部分可以重写,部分不可以?怎么办?只要让指定的方法最终化就可以了。
2,final修饰的方法是最终方法,不可以给重写。
3,final修饰的变量是一个常量,只能被赋值一次。
【什么时候会在程序中定义final常量呢?】
当程序中一个数据使用时是固定不变的,这时为了增加阅读性,可以该该数据起个名字。
这就是变量,为了保证这个变量的值不被修改,加上final修饰,这就一个阅读性很强的常量。
书写规范,被final修饰的常量名所有的字母都是大写的。如果由多个单词组成单词间通过 _ 连接。

*/
/*final*/class Fu
{
/*final*/ void show()
{
//调用到一些系统的功能。
//功能的内容是不可以改变的。
}
} class Zi extends Fu
{
static final int number = ;//最终化的是显示初始化值。
static final double PI = 3.14;
//重写
void show()
{
final int count = ;
// count = 2;
System.out.println(count);
}
} class FinalDemo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}

二 抽象类

2.1 产生 

/*
描述狗,行为:吼叫。
描述狼,行为:吼叫。
发现他们之间有共性,可以进行向上抽取。
当然是抽取它们的所属共性类型:犬科。
犬科这类事物:都具备吼叫行为,但是具体怎么叫,是不确定的,是由具体的子类来明确的。
这时在描述犬科时,发现了有些功能不具体,这些不具体的功能,需要在类中标识出来,通过java中的关键字abstract(抽象)。
定义了抽象函数的类也必须被abstract关键字修饰,被abstract关键字修饰的类是抽象类。
*/
//抽象类:在描述事物时,没有足够的信息描述一个事物,这时该事物就是抽象事物。

2.2 抽象类的特点

1,抽象类和抽象方法都需要被abstract修饰。
抽象方法一定要定义在抽象类中。
2,抽象类不可以创建实例,原因:调用抽象方法没有意义。
3,只有覆盖了抽象类中所有的抽象方法后,其子类才可以实例化。
否则该子类还是一个抽象类。

之所以继承,更多的是在思想,是面对共性类型操作会更简单。

【细节问题】
1,抽象类一定是个父类?
是的,因为不断抽取而来的。

2,抽象类是否有构造函数?
,虽然不能给自己的对象初始化,但是可以给自己的子类对象初始化。
抽象类和一般类的异同点:
         相同:
1,它们都是用来描述事物的。
2,它们之中都可以定义属性和行为。

 不同:
1,一般类可以具体的描述事物。
抽象类描述事物的信息不具体
2,抽象类中可以多定义一个成员:抽象函数。
3,一般类可以创建对象,而抽象类不能创建对象。

3,抽象类中是否可以不定义抽象方法。
是可以的,那这个抽象类的存在到底有什么意义呢?仅仅是不让该类创建对象。

4,抽象关键字abstract不可以和哪些关键字共存?
1,final:
2,private:
3,static:

*/

abstract class 犬科 //extends Object
{
static abstract void 吼叫();//抽象函数。需要abstract修饰,并分号;结束
} //代码体现。
class Dog extends 犬科
{
void 吼叫()
{
System.out.println("汪汪汪汪");
}
} class Wolf extends 犬科
{
void 吼叫()
{
System.out.println("嗷嗷嗷嗷");
}
} class AbstractDemo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}

2.2 例子

/*
需求:公司中程序员有姓名,工号,薪水,工作内容。
项目经理除了有姓名,工号,薪水,还有奖金,工作内容。
对给出需求进行数据建模。

在问题领域中先找寻其中涉及的对象。
程序员
属性:姓名,工号,薪水
行为:工作

项目经理
属性:姓名,工号,薪水,奖金
行为:工作

这些对象是否有关系呢?因为发现了他们之间的共性,应该存在着关系。
可以将他们的共性向上抽取到共性类型:员工。
员工:
属性:姓名,工号,薪水
行为:工作
发现员工的工作内容本身就不具体。应该是抽象的,由具体的子类来体现的。

一定要动手!

*/

abstract class Employee
{
private String name;
private String id;
private double pay;
/**
构造一个员工对象,一初始化就具备着三个属性。
*/
public Employee(String name,String id,double pay)
{
this.name = name;
this.id = id;
this.pay = pay;
}
/**
工作行为。
*/
public abstract void work();
} //具体的子类:程序员。
class Programmer extends Employee
{
public Programmer(String name,String id,double pay)
{
super(name,id,pay);
}
public void work()
{
System.out.println("code....");
}
} //具体的子类:经理。
class Manager extends Employee
{
//特有属性。
private double bonus;
public Manager(String name,String id,double pay,double bonus)
{
super(name,id,pay);
this.bonus = bonus;
}
public void work()
{
System.out.println("manage");
}
} class AbstractTest
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}

三 接口

3.1 产生

/*
抽象类中可以定义抽象方法的 。
当一个抽象类中的方法全是抽象的。
这时,可以通过另一种特殊的形式来体现。

用接口来表示。

3.2 定义

接口该如何定义呢?

interface

abstract class Demo
{
abstract void show1();
abstract void show2();
}
*/
/*

3.3 接口中的成员

接口中的成员已经被限定为固定的几种。
【接口的定义格式先介绍两种:】
1,定义变量,但是变量必须有固定的修饰符修饰,public static final 所以接口中的变量也称之为常量。
2,定义方法,方法也有固定的修饰符,public abstract

注意:如果你不写编译器会给你自动加上 

例如当你只写一个final的时候,编译器会给你自动加上public static final
接口中的成员都是公共的。

3.4 接口的特点

1,接口不可以创建对象。
2,子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化。
否则子类是一个抽象类。

*/
interface Demo//定义一个名称为Demo的接口。
{
public static final int NUM = ;
public abstract void show1();
public abstract void show2();
}

//定义子类去覆盖接口中的方法。子类必须和接口产生关系,类与类的关系是继承类与接口之间的关系是 实现。通过 关键字 implements   注意: 定义接口时命名  名+Impl

class DemoImpl implements Demo//子类实现Demo接口。
{
//重写接口中的方法。
public void show1(){}
public void show2(){}
}

【接口最重要的体现】
解决多继承的弊端。将多继承这种机制在java中通过多实现完成了。


interface A
{
void show1();
}
interface B
{
void show2();
}
class C implements A,B// 多实现。同时实现多个接口。
{
public void show1(){}
public void show2(){}
}

【怎么解决多继承的弊端呢?】
弊端:多继承时,当多个父类中有相同功能时,子类调用会产生不确定性。
其实核心原因就是在于多继承父类中功能有主体,而导致调用运行时,不确定运行哪个主体内容。
为什么多实现就解决了呢?
因为接口中的功能都没有方法体,由子类来明确。

interface A
{
void show();
}
interface B
{
void show();
}
class C implements A,B// 多实现。同时实现多个接口。
{
public void show();
} C c = new C();
c.show();

【基于接口的扩展。】

class Fu
{
public void show(){}
}
//子类通过继承父类扩展功能,通过继承扩展的功能都是子类应该具备的基础功能。
//如果子类想要继续扩展其他类中的功能呢?这时通过实现接口来完成。
interface Inter
{
pulbic void show1();
}
class Zi extends Fu implements Inter
{
public void show1()
{ }
}

[ 接口的好处]

接口的出现避免了单继承的局限性。
父类中定义的事物的基本功能。
接口中定义的事物的扩展功能。

3.5 接口出现后的一些小细节

1,类与类之间是继承(is a)关系,类与接口之间是实现(like a)关系,
接口与接口之间是继承关系,而且可以多继承。

interface InterA
{
void show1();
}
interface InterAA
{
void show11();
}
interface InterB extends InterA,InterAA//接口的多继承。
{
void show2();
} class Test implements InterB
{
public void show1(){}
public void show2(){}
public void show11(){}
} class InterfaceDemo
{
public static void main(String[] args)
{
DemoImpl d = new DemoImpl();
d.show1();
d.show2(); }
}

3.6 接口的思想

举例:笔记本电脑,USB接口的故事。

1,接口的出现对功能是实现了扩展。
2,接口的出现定义了规则。
3,接口的出现降低了耦合性(解耦)。

接口的出现,完成了解耦,说明有两方,一方在使用这个规则,另一方在实现这个规则。
比如笔记本电脑使用这个规则,而外围设备在实现这个规则。

3.7  接口和抽象类的区别

描述事物。
:按照功能分类: 导盲犬,缉毒犬...

犬的行为
吼叫();
吃饭();

abstract class 犬
{
public abstract void 吼叫();
public abstract void 吃饭(); }
class 缉毒犬 extends 犬
{
public void 吼叫(){}
public void 吃饭(){}
public void 缉毒(){}
} //对于缉毒,有可能还有缉毒猪,具备者缉毒功能,应该将缉毒功能抽取。
//对缉毒进行描述。
abstract class 缉毒
{
public abstract void 缉毒();
}

缉毒犬既需要犬的功能又需要缉毒的功能。
无法直接多继承。
是否可以多实现呢?可以的。
犬是接口,缉毒也是接口。缉毒犬多实现即可。
类负责描述的是事物的基本功能。接口负责描述事物的扩展功能。
缉毒犬是犬中一种。is a 关系,
将犬定义成类。而缉毒是犬的一个扩展功能。这时将缉毒定义接口。

这时描述就变成了这样:

interface 缉毒able
{
public abstract void 缉毒();
} class 缉毒犬 extends 犬 implements 缉毒able
{
public void 吼叫(){code..}
public void 吃饭(){}
public void 缉毒(){}
}

总结:
1,抽象类是描述事物的基本功能,可以定义非抽象的方法。
接口中定义只能是抽象方法,负责功能的扩展。
2,类与类之间是继承关系 is a关系。
类与接口之间是实现关系 like a 关系。


open();
close(); 报警门。 class 门
{
}
interface 报警
{
} class
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}

java-继承进阶_抽象类_接口的更多相关文章

  1. JAVA 继承基本类、抽象类、接口

    Java是一个面向对象的语言,java面向对象一般有三大特征:封装.继承.多态. 封装:就是把一些属性和方法封装到一个类里. 继承:就如子类继承父类的一些属性和方法. 多态:就如一个父类有多个不同特色 ...

  2. java面向对象_抽象类和接口

    一.抽象类 1.抽象方法:由abstract修饰.只有定义没有方法体.用一个分号结尾. 2.抽象类: 1)包含抽象方法的类必须是抽象类 2)由abstract修饰 3)不能被实例化 4)抽象类如果不被 ...

  3. lesson 4 再谈继承多态,抽象类和接口

    再谈多态,抽象类和接口 上一次博客已经概念性的概述了继承多态,抽象类和接口,这次来具体的谈一谈他们之间的联系和需要注意的地方. 一.继承和多态:Inheritance (继承) & Polym ...

  4. Java面向对象_抽象类、接口

    一.抽象类 概   念:很多具有相同特征和行为的对象可以抽象为一个类:很多具有相同特征和行为的类可以抽象为一个抽象类 关键字:abstract 规   则:1.抽象类可以没有抽象方法,有抽象方法的类必 ...

  5. java继承多态和抽象类接口

    一.继承 通过扩展一个已有的类,并继承该类的属性和行为,来创建一个新的类.已有的称为父类,新的类称为子类(父类派生子类,子类继承父类).(1)继承的优点:    ①代码的可重用性:    ②父类的属性 ...

  6. java提高篇(五)-----抽象类与接口

    接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念 ...

  7. 十、Java基础---------面向对象之抽象类与接口

    抽象类(abstract)     当编写一个类时,时常会为该类定义一些方法,这些方法的使用用以描述该类的行为方式,那么这些方法都有具体的方法体.但是在某些情况下,某个父类只是知道子类应该包含怎样的方 ...

  8. Java中多态、抽象类和接口

    1:final关键字(掌握) (1)是最终的意思,可以修饰类,方法,变量. (2)特点: A:它修饰的类,不能被继承. B:它修饰的方法,不能被重写. C:它修饰的变量,是一个常量. (3)面试相关: ...

  9. Java学习日记-7 抽象类和接口

    一.抽象类 abstract修饰:类和类中的方法 抽象方法:abstract type name(parameter-list);(abstract不能修饰static方法和构造函数) 引用:抽象类有 ...

  10. (转)java提高篇(五)-----抽象类与接口

    接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念 ...

随机推荐

  1. mybatis接口映射

    通过sqlSession.getMapper();方法获取映射的接口及方法 sqlSession调用Configuration的getMapper方法,方法中使用了mapperRegistry.get ...

  2. 绕过CDN查找真实IP方法总结

    CDN的全称是Content Delivery Network,即内容分发网络.CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡.内容分发.调度等功能模 ...

  3. Android基础控件TextClock和Chronometer的使用

    1.简介 DigitalClock, TextClock,AnalogClock,Chronometer其中DigitalClock和AnalogClock废弃了! TextClock是在Androi ...

  4. css 超出两行省略号,超出一行省略号

    参考:https://www.cnblogs.com/yangguojin/p/10301981.html 超出一行省略: p{ white-space:nowrap; overflow:hidden ...

  5. 初识splay

    这东西都没什么板子着实让我很难受啊,只能到网上抄抄补补, 记下两个用到的博客 https://blog.csdn.net/clove_unique/article/details/50630280 h ...

  6. PKUWC&SC 2018 刷题记录

    PKUWC&SC 2018 刷题记录 minimax 线段树合并的题,似乎并不依赖于二叉树. 之前写的草率的题解在这里:PKUWC2018 minimax Slay the Spire 注意到 ...

  7. css 实现单行以及多行文本溢出显示省略号

    如果实现单行文本的溢出显示省略号大家都知道用text-overflow:ellipsis属性来,当然还需要加上宽度width属性. 实现方法: ``` overflow: hidden; text-o ...

  8. 使用gRPC-Gateway快速构建微服务-双向认证下rpc-gateway使用(同时提供rpc和http接口)

    https://github.com/grpc-ecosystem/grpc-gateway 在grpc之上加一层代理并转发,转变成protobuf格式来访问grpc服务 安装 go get -u g ...

  9. [code]彩色图像直方图均衡化 histogram_rgb

    //2013.9 eageldiao #ifdef HISTOGRAM_RGB unsigned ]; unsigned intncount[]={},ncount1[]={},ncount2[]={ ...

  10. 《数据结构与算法分析——C语言描述》ADT实现(NO.01) : 栈(Stack)

    这次的数据结构是一种特殊的线性表:栈(Stack) 栈的特点是后入先出(LIFO),可见的只有栈顶的一个元素. 栈在程序中的地位非常重要,其中最重要的应用就是函数的调用.每次函数调用时都会创建该函数的 ...