1、继承:在描述多个事物中,发现这些类有共通点,则可以把这些共同点进行提取
生成一个新的类别,那么这个新的类别就是其他类的父类(也称超类或基类),其他类称之为子类。
2、继承体系:子类继承自父类,java中所有类都有父类,如果没有显示的去继承一个父类的话,那么默认父类是Object。
3、继承也可以称之为是封装的一种体现,将多个类的共通点抽取,封装成一个新类
封装的体现:代码重复->封装成函数->可以重复调用,减少代码冗余
属性和行为分开->类(把属性和行为封装在一起)->方便统一管理->形成面向对象
多个类有共同点->将其抽取,形成父类 ->子类通过继承得到父类的属性和行为
4、 java中,类不能实现多继承
但是类可以多实现接口
接口可以多继承接口!
5、什么时候定义继承
继承的前提是类与类必须是同一体系;不能为了获取某些类的功能而去继承
/*封装 代码重复->函数->重复调用 减少代码冗余
属性和行为分开->类->方便统一管理->面向对象
多个类有共同点->父类 子类->继承
继承:在描述多个事物中,发现这些类有共通点,则可以把这些共同点进行提取
生成一个新的类别,那么这个新的类别就是其他类的父类,其他类称之为子类
子类继承自父类
*/
public class OOPDemoE {
}
class Bird{
void fly(){}
}
class Person extends Bird{//错误,人和鸟不是同一体系,最多是同一级别,属于不同分支
//人不能为了获得飞的方法而去继承鸟
String name;
String age;
void sleep(){}
}
class Student extends Person{
void study(){
}
}
class Worker extends Person{
void work(){}
}
6、继承中子类和父类成员的特点(主函数中创建的是子类的对象)
(1)成员变量的特点:在非私有的情况下:父类有 子类没 则调用父类的;父类有 子类有 则调用子类的;父类没 子类有 则调用子类的(父有,子无,用父;其余用子)
(2)成员函数的特点:
在非私有的情况下:父类有 子类没 则调用父类的;
父类有 子类有 则调用子类,这也叫函数的重写 (函数重载是在同一类中参数列表不同,子类重写父类函数时,重写的函数权限大于等于父类该函数的权限((函数的权限有4种:public 默认 protect private)
父类无,子类有,调用子类的。
总结:父有,子无,用父;其余用子
(3)构造函数的特点:
子类在创建对象时,父类的构造函数也执行了,原因不是因为要创建父类的对象,而是要为子类进行一些初始化,虽然执行了父类的构造函数,不代表创建类父类对象。
如果子父类的构造函数都是无参的,且显示的写出来了,在创建子类对象时,默认的super()使子类和父类的构造函数都调用了;
如果父类构造函数有参,子类构造函数无参,默认的super()无法找到无参的父类构造函数,代码报错,此时,必须显示的写出super(),并写出super里的参数,必须在第一行。
只要父类的构造函数是无参的,子类构造函数中super()就不用显示的写出来;父类的构造函数的有参的话,子类构造函数中super()就要写出来,而且super中的参数类型随父类构造函数而变化。
构造函数通过this() 可单向调用,对父类构造函数的调用super必须在第一行,对本类中调用其他构造函数 this也必须在第一行。
在同一个包下创建类Zi类和Fu类,就不能在另一个Demo中创建了。
/*封装 代码重复->函数->重复调用 减少代码冗余
属性和行为分开->类->方便统一管理->面向对象
多个类有共同点->父类 子类->继承
继承:在描述多个事物中,发现这些类有共通点,则可以把这些共同点进行提取
生成一个新的类别,那么这个新的类别就是其他类的父类,其他类称之为子类
子类继承自父类
父类有 子类没 则用父类的
父类有 子类有 则子类的
父类没 子类有 则子类的
z.show();
子父类中 构造函数的特点
子类在创建对象时 父类的构造函数也执行了?
不是因为要创建父类的对象 而是要为子类进行一些初始化
super不是指父类的对象 而是指父类的(也就是父类的代码区、方法区,包括堆里的空间)空间
对父类构造函数的调用super 必须在第一行
对本类中调用其他构造函数 this必须在第一行
super不是指父类的对象 而是指父类的(方法区 堆)空间
*/
public class OOPDemoE {
public static void main(String[] args) {
Zi z=new Zi(2);
//System.out.println(z.sum);//结果为3
//System.out.println(z.sum);父类的私有成员子类无法直接调用
System.out.println(z.sum);//结果为10
z.show();//这是父类的方法
System.out.println(z.num3);
//子类在创建对象时,父类的构造函数也执行了
}
}
class Fu{
int sum=3;
int num3;
//private int sum=3;
Fu(int a){
//a=80;
System.out.println("这是父类的构造函数");
}
void show(){
System.out.println("这是父类的方法");
}
}
class Zi extends Fu{
int sum=10;
Zi(){
//super(80);//代表父类隐藏的空间
this(0);
System.out.println("这是子类的构造函数");
}
Zi(int a){
this(a,0);
}
Zi(int a,int b){
//this(a,b);报错
super(10);//必须写这一句才不报错
//这几个构造函数最后肯定有一个必须调用父类的
}
public void show(){
System.out.println("这是子类的方法");
}
}
==================================================================
public class OOPDemoF {
public static void main(String[] args) {
Son son=new Son();
son.show();
son.test();
}
}
class Father{
int haha;
Father(){
haha=100;
show();//重名,用子类的
}
void show(){
System.out.println("Father show "+haha);
}
}
class Son extends Father{
int xixi=50;
Son(){
//super()可写可不写
show();//子类的show中的xixi默认初始化为0,父类中的构造函数执行完毕,执行子类的构造函数,xixi显示初始化为50
test();
xixi=200;//针对性初始化
show();
test();
}
void show(){
System.out.println("Son show "+haha+":"+xixi);
}
void test(){
System.out.println("Son test "+haha+":"+xixi);
}
}
结果:Son show 100:0 结果:Father show 10(没有重写父类的方法)
Son show 100:50 Father show 100
Son test 100:50 Son test 100:50
Son show 100:200 Father show 100
Son test 100:200 Son test 100:200
Son show 100:200 Father show 100
Son test 100:200 Son test 100:200
父子继承
7、继承中静态成员的特点
静态成员变量的特点:在非私有的情况下:父类有 子类没 则调用父类的;父类有 子类有 则调用子类的;父类没 子类有 则调用子类的(父有,子无,用父;其余用子)成员变量不能和静态变量重名。
区分子类和父类的变量和函数用super,区分局部和当前对象的变量用this。
public class OOPDemoG {
public static void main(String[] args) {
Daughter d=new Daughter();
System.out.println(d.num);
d.show();
}
}
class Mother{
static int num=3;
void show(){
System.out.println("Mother show");
}
}
class Daughter extends Mother{
static int num=5;
void show(){
int num=10;
System.out.println(num);//就近原则,主函数中调用show方法打印num=10
System.out.println(this.num);//5静态的两种调用方法
System.out.println(Daughter.num);//5,类名.方法和对象.方法
System.out.println(super.num);//3,父类的静态
}
}
8、final关键字
final修饰变量,代表该变量不可修改;final修饰函数,代表该函数不可重写;final修饰类,代表该类不可被继承。
public class OOPDemoA {
//final static int b;静态变量为final,必须初始化
//final int a;成员变量为final,必须初始化
public static void main(String[] args) {
//局部变量为final可以不用初始化
final int a=3;//值不能被修改
//a=4;he final local variable a cannot be assigned.
final int b;
b=4;//将4在常量池中的地址给b
//b=5;又把将5在常量池中的地址给b,地址无法改变了
final Demo d=new Demo();
d.a=20;//可以
/*不可修改,仅仅是指变量所存的地址,不可修改
new Demo() 对象在堆里面 地址假设为0x666
d=0x666 所以是说0x666不能被改变,通过地址找对象里的属性,属性可以变*/
出错://d=new Demo();he final local variable d cannot be assigned
DemoSub ds=new DemoSub();
ds.show();//子类可以调用父类的final方法,但不能重写
}
}
final class Demo{
int a=10;
public final void show(){
System.out.println("Demo show");
}
}
//he type DemoSub cannot subclass the final class Demo不能继承final类
class DemoSub extends Demo{
// public void show(){
// Cannot override the final method from Demo不能重写父类的final方法
// }
}