继承:
1. 概述:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无序再去定义这些属性和行为,只要继承那个类即可。
2. 那多个类成为子类,单独这个类成为父类或者基类超类,
3.子类可以直接访问父类重的非私有的属性和行为。
4.通过extends关键字让类与类之间产生继承关系
继承的特点:
1、继承的而出现提高了代码的复用性。
2、继承的出现让类与类之间产生了关系,提供了多态的前提。
3、Java支持单继承,对于多继承,java保留了这种机制并进行了改良,避免了多继承调用时的不确定性。
它这个是发送端,首先 要关联你要发送的源文件,可以单独在
对于使用一个继承体系。
1、查阅顶层类中的 共性内容了解该体系的基本功能。
2、创建该体系的子类对象。
简单一句话:可以多个子类继承一个父类,但是不一个 类继承多个父类,在java中是不允许的。
什么时候使用继承?
当事物之间存在着所属关系时,就可以使用继承,
所属:xxx是yyy的一种,即x继承y
如果A真继承了B,B中的锁有的功能是不是A都具备了。
注意:千万不要为了获取其他类的功能,简化代码而继承。
必须是类与类之间有所属关系才可以继承。
继承子父类中的成员变化。
1.成员变量:
当子父类中出现同名的成员变量时,可以使用super关键字来区分,父类的成员变量。
Super和this用法很相似,this代表的是本类的对象,super代表父类的所属的空间,
先有父类在有子类。面试中会出现,开发中几乎没有,因为父类的成员都是从下到上抽取的,子类中还保留相同的变量干嘛?
2.成员函数
当子父类出现一模一样(返回值、函数名、参数列表全部相同)的函数时,就会出现调用时运行子类的方法的情况。
这种情况,形象成为覆盖或者重写或者覆写。
什么时候用覆盖?
当对一个类中的功能的内容进行重新定义时,可以定义该类的子类,并保留父类中的功能声明,重新定义功能内容,并建立子类对象调用该功能。
当子父类中出现一模一样的函数时,就会出现调用时运行子类的方法的情况。
这种情况,形象的称为 覆盖或者重写或者叫做覆写 override。
什么时候用覆盖?
当对一个类中的功能的内容进行重新定义的时,可以定义该类的子类,并保留父类中的功能声明,
重新定义功能内容。并建立子类对象调用该功能。
覆盖小细节:
1,子类方法覆盖父类方法时,权限必须大于等于父类的权限。
2,静态只能覆盖静态,或者被静态覆盖。
代码演示:
class Fu
{
public static void show()
{
System.out.println("fu show");
}
}
class Zi extends Fu
{
public static void show()
{
System.out.println("zi show");
}
}
class ExtendsDemo3
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
Phone p = new Phone();
NewPhone p = new NewPhone();
p.show();
}
}
描述手机。来单显示 显示 号码。
class Phone
{
void show()
{
System.out.println("fu number"); }
}
为了对Phone类中的来电显示功能进行改变。
定义了一个子类,保留了父类中功能的声明,但是重新定义了功能的内容。
这就是覆盖的应用。
class NewPhone extends Phone
{
void show()
{
super.show();
System.out.println("name");
System.out.println("pic");
}
}
3、构造函数
特点:
在运行时,发现父类构造方法先运行了,然后才是子类构造函数。
原因:是因为子类的所有的构造函数中都有一句默认的隐式语句:super();会默认调用父类重空参数的构造函数。
为什么有super默认语句呢?
因为子类对象在初始化时,必须要到父类先去初始化。
为什么要到父类中去初始化呢?
因为子类继承了父类,可以获取父类中的数据,所以在使用父类数据之前必须要明确父类是如何对自己的成员进行初始化的。
这也是子类一定要访问父类构造函数的原因。所以父类的构造函数有两个作用:1、给本类初始化
如果父类中的没有空参数的构造函数,
那么此时在手动就必须通过super语句或this语句指定要访问父类的构造函数。
注意:super关键字必须定义第一行。任何构造函数中的默认第一句都是super.
面试题:为什么super和this不能再构造函数中同时出现?
为什么super语句必须放在第一行?
因为只有父类初始化完之后才初始化子类。
Object是java中所有类的父类。
以上就是一个子类的实例化过程。
代码演示:
class Fu extends Object
{
int num ;
Fu()
{
super();
System.out.println("fu.......");
}
Fu(int x)
{
num = 10;
System.out.println("fu run..."+x);
}
}
class Zi extends Fu
{
Zi()
{
//super();
System.out.println("zi.....");
}
Zi(int x)
{
this();
super();
super(x);
System.out.println("zi run..."+x);
}
}
class ExtendsDemo4
{
public static void main(String[] args)
{
new Zi(5);
new Zi();
}
}
fiinal关键字
final : 最终。作为一个修饰符,
1,可以修饰类,函数,变量。
2,被final修饰的类不可以被继承。为了避免被继承,被子类复写功能。
3,被final修饰的方法不可以被复写。
4,被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,有可以修饰局部变量。
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。
而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成。
单词间通过_连接。
5,内部类定义在类中的局部位置上是,只能访问该局部被final修饰的局部变量。
抽象类
当多个类中出现相同功能,但是功能主体不同,
这是可以进行向上抽取。这时,只抽取功能定义,而不抽取功能主体。
抽象:看不懂。
抽象类的特点:
1,抽象方法一定在抽象类中。
2,抽象方法和抽象类都必须被abstract关键字修饰。
3,抽象类不可以用new创建对象。因为调用抽象方法没意义。
4,抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。
如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
抽象类和一般类没有太大的不同。
该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西。
这些不确定的部分,也是该事物的功能,需要明确出现。但是无法定义主体。
通过抽象方法来表示。
抽象类比一般类多个了抽象函数。就是在类中可以定义抽象方法。
抽象类不可以实例化。
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
抽象类中是否有构造函数?
有,抽象类是一个父类,要给子类提供实例的初始化。
接口
接口:初期理解,可以认为是一个特殊的抽象类
当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。
class用于定义类
interface 用于定义接口。
接口定义时,格式特点:
1,接口中常见定义:常量,抽象方法。
2,接口中的成员都有固定修饰符。
常量:public static final
方法:public abstract
记住:接口中的成员都是public的。
接口:是不可以创建对象的,因为有抽象方法。
需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。
否则子类是一个抽象类。
接口可以被类多实现,也是对多继承不支持的转换形式。java支持多实现。
interface Inter
{
public static final int NUM = 3;
public abstract void show();
}
interface InterA
{
public abstract void show();
}
class Demo
{
public void function(){}
}
class Test extends Demo implements Inter,InterA
{
public void show(){}
}
interface A
{
void methodA();
}
interface B //extends A
{
void methodB();
}
interface C extends B,A
{
void methodC();
}
class D implements C
{
public void methodA(){}
public void methodC(){}
public void methodB(){}
}
class InterfaceDemo
{
public static void main(String[] args)
{
Test t = new Test();
System.out.println(t.NUM);
System.out.println(Test.NUM);
System.out.println(Inter.NUM);
}
}