标签:为什么 数据 种类 问题: 打印 部分 创建对象 eth 分享
面向对象(Object Oriented)
1、 继承的概述[extends]
继承好处:1, 提高代码复用性;
2, 让类与类之间产生关系,给多态提供前提。
Java中支持单继承[单继承:一个子类之只能有一个直接父类],不直接支持多继承,但对C++中的多继承机制进行改良。
多个类可以继承一个父类
class A{}
class B extends A{}
class C extends A{}
多层继承
class A{}
class B extends A{}
class C extends B{}
多继承:一个子类可以有多个直接父类(Java中不允许,进行改良)在Java中通过“多实现”方式体现
class A{}
class B{}
class C extends A,B{}
多继承存在问题:不直接支持,多个父类中有相同的成员,会产生调用的不确定性。
1 class A 2 { 3 void show() 4 { 5 System.out.println("A"); 6 } 7 } 8 class B 9 { 10 void show() 11 { 12 System.out.println("B"); 13 14 } 15 } 16 17 class C extends A,B{} 18 new C().show();
Java支持多层(多重)继承
C继承B;B继承A
就会出现继承体系,当要使用一个继承时;
1, 查看该体系中的顶层类,了解该体系的基本功能。
2, 创建体系中的最子类对象,完成功能的使用。
ExtendsDemo
1 //extends继承 2 class Person 3 { 4 String name; 5 int age; 6 } 7 //学生类继承人的属性 8 class Student extends Person 9 { 10 // String name; 11 // int age; 12 void study() 13 { 14 System.out.println("name="+name+" age="+age+" is study study"); 15 } 16 } 17 //工人类继承人的属性 18 class Worker extends Person 19 { 20 // String name; 21 // int age; 22 void work() 23 { 24 System.out.println("name="+name+" age="+age+" is work work"); 25 } 26 } 27 class ExtendsDemo 28 { 29 public static void main(String[] args) 30 { 31 Student s=new Student(); 32 s.name="张三"; 33 s.age=21; 34 s.study(); 35 Worker w=new Worker(); 36 w.name="李四"; 37 w.age=30; 38 w.work(); 39 } 40 }
2、子父类中成员的特点体现
2.1 成员变量
当本类的成员变量和局部变量同名时用this
当子父类中的成员变量同名时用super
This:代表一个本类对象的引用
Super:代表一个父类空间
ExtendsDemo2
1 //子父类成员变量 2 class Fu 3 { 4 int num=4; 5 } 6 class Zi extends Fu 7 { 8 int num=5; 9 void show() 10 { 11 //this访问本类的num,super访问父类的num 12 System.out.println(this.num+"\t"+super.num); 13 } 14 } 15 class ExtendsDemo2 16 { 17 public static void main(String[] args) 18 { 19 Zi z=new Zi(); 20 z.show(); 21 } 22 }
2.2 成员函数
当子父类中出现成员函数一样情况,运行子类的函数(覆盖操作)
函数特性:
1,重载 同一个类中
2,覆盖 子类中(也称重写)
覆盖注意事项:
1,子类方法覆盖父类方法时,子类权限必须>=父类的权限;
2,静态只能覆盖静态,或被静态覆盖。
ExtendsDemo3
1 //子父类成员函数 2 class Fu 3 { 4 void show() 5 { 6 System.out.println("父类function"); 7 } 8 } 9 class Zi extends Fu 10 { 11 void show() 12 { 13 System.out.println("子类function"); 14 super.show();//访问父类的show 15 } 16 } 17 class ExtendsDemo3 18 { 19 public static void main(String[] args) 20 { 21 Zi z=new Zi(); 22 z.show(); 23 } 24 }
2.3 覆盖的应用
当对一个类进行子类的扩展时,子类需要保留父类功能声明;但需要定义子类中该功能能的特有内容时,就使用覆盖操作
1 //覆盖的应用 2 //定义1.0版本Phone【call 、显示来电两个功能】 3 class Phone 4 { 5 void call() 6 { 7 System.out.println("打电话功能"); 8 } 9 void show() 10 { 11 System.out.println("Phone显示来电信息"); 12 } 13 } 14 //定义2.0版本Phone 【新增查看归属地、联系人照片功能,保留1.0版本原有功能】 15 class newPhone extends Phone 16 { 17 void show() 18 { 19 super.show(); 20 System.out.println("显示号码归属地"); 21 System.out.println("显示联系人照片"); 22 } 23 } 24 class ExtendsTest 25 { 26 public static void main(String[] args) 27 { 28 newPhone p=new newPhone(); 29 p.call(); 30 p.show(); 31 } 32 }
2.4 构造函数
子父类的构造函数:子类构造对象时,访问子类构造函数,父类也运行=>子类构造函数中第一行有一个默认隐式语句:super();
子类实例化过程:子类所有的构造函数默认都会访问父类中空参数的构造函数
Zi构造函数有三句语句:
1,super();//默认的空参数 隐式语句
2,本身的定语语句;
3,return;
ExtendsDemo4
1 //子父类构造函数 - 子类实例化过程 2 class Fu 3 { 4 // 定义无参、有参的父类构造函数 5 Fu() 6 { 7 System.out.println("A 父类构造函数"); 8 } 9 Fu(int x) 10 { 11 System.out.println("B 父类构造函数 "+x); 12 } 13 } 14 class Zi extends Fu 15 { 16 // 定义子类的无参、有参的构造函数 17 Zi() 18 { 19 // super();//隐式语句 调用父类用参数构造函数 20 System.out.println("C 子类构造函数"); 21 // return; 22 } 23 Zi(int x) 24 { 25 // super(x);// 加载带参数的super(x) sop= >B、D 26 // super();//默认访问隐式语句 sop => A、D 27 System.out.println("D 子类构造函数 "+x); 28 } 29 } 30 class ExtendsDemo4 31 { 32 public static void main(String[] args) 33 { 34 new Zi(5); 35 36 } 37 }
3、关键字:final
//继承弊端:打破封装性
1,final修饰类:不能被继承
2,final修饰方法:不能被覆盖(重写)
3, final修饰的变量(成员变量、局部变量)是一个常量,且只能赋值一次
4, final 修饰成员变量必须要有初始化值
为什么final修饰变量?
程序中如果一个数据是固定的,那么直接使用这个数据就可以了,但是阅读性差,所以用final去修饰。
写法:常量所有字母大写,多个单词,中间_连接
FinalDemo
1 //final 修饰符 2 //final 修饰类 3 final class Fu 4 { 5 //final 修饰方法 6 final void method() 7 { 8 //调用底层系统资源 9 } 10 } 11 class Zi extends Fu 12 { 13 //final 修饰变量 14 final double PI=3.14; 15 // final int x;//报错:可能尚未初始化变量x 16 static final int x=7; 17 void method() 18 { 19 System.out.println(PI); 20 } 21 } 22 class FinalDemo 23 { 24 public static void main(String[] args) 25 { 26 Zi z=new Zi(); 27 z.method(); 28 } 29 }
4、抽象类【abstract】
4.1 抽象的定义
抽象就是从多个事物中将共性的,本质的内容抽取出来。
例如:狼和狗共性都是犬科,犬科就是抽象出来的概念。
4.2 抽象类:
Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。
4.3 抽象方法的由来【具有相同的功能的声明,具体实现方式却不同】
多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。
例如:狼和狗都有吼叫的方法,可是吼叫内容是不一样的。所以抽象出来的犬科虽然有吼叫功能,但是并不明确吼叫的细节。
4.4 抽象的特点
1,抽象类和抽象方法必须用abstract关键字来修饰。
2,抽象方法只有方法声明,没有方法体,定义在抽象类中。
格式:修饰符 abstract 返回值类型 函数名(参数列表) ;
3,抽象类不可以被实例化,也就是不可以用new创建对象。
原因如下:抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。例如:犬科是一个抽象的概念,真正存在的是狼和狗。
而且抽象类即使创建了对象,调用抽象方法也没有意义。
4,抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。
4.5 抽象类的常见问题?
a,抽象类中有构造函数吗?
有,用于给予子类对象进行初始化。
b,抽象类可以不定义抽象方法吗?
可以(少见,目的是不让该类创建对象;AWT的适配器对象就是这种类),通常该类中的方法有方法体,却没有内容;
c,抽象关键字不可以和那些关键字共存?
private=>非法的修饰符组合: abstract和private(抽象需要被覆盖)
static =>非法的修饰符组合: abstract和static
final =>非法的修饰符组合: abstract和final
d,抽象类和一般类的异同点?
相同点:抽象类和一般类都是用来描述事物,都在内部定义成员。
不同点:1.一般类有足够的信息描述事物;
抽象类描述事物的信息具有局限性。
2.一般类中不能定义抽象方法,只能定义非抽象方法;
抽象类中可定义抽象方法,同时也可定义非抽象方法。
3.一般类可被实例化,抽象类不可被实例化
e,抽象类一定是个父类?
是的。(需要子类覆盖其方法后才可对子类实例化)
AbstractDemo
1 //抽象类的由来 2 //具有相同的功能的声明,具体实现方式却不同 3 //定义一个抽象Demo类 4 abstract class Demo 5 { 6 //定义一个抽象方法show 7 abstract void show(); 8 } 9 //DemoA继承Demo类 10 class DemoA extends Demo 11 { 12 //实现show()方法 13 void show() 14 { 15 System.out.println("demo show A"); 16 } 17 } 18 class DemoB extends Demo 19 { 20 void show() 21 { 22 System.out.println("demob show B"); 23 } 24 } 25 class AbstractDemo 26 { 27 public static void main(String[] args) 28 { 29 DemoA d=new DemoA();//创建DemoA对象 30 d.show();//调用show方法 31 } 32 }
5、接口【interface】
5.1 接口的定义
当一个抽象类中的方法都是抽象的时候,这时可以将该类用接口定义 interface;接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。
对于接口中常见的成员:这些成员都有固定的修饰符(默认存在的)
1,全部常量:public static final
2,抽象方法:public abstract
InterfaceDemo
1 interface Demo 2 { 3 //定义接口int属性值 4 /*public static final int NUM=2018; 5 public abstract void show1(); 6 public abstract void show2();*/ 7 8 public int NUM=2018; 9 public void show1(); 10 public void show2(); 11 12 } 13 //实现接口 14 class DemoImpl implements Demo 15 { 16 public void show1() 17 { 18 } 19 public void show2() 20 { 21 } 22 23 } 24 class InterfaceDemo 25 { 26 public static void main(String[] args) 27 { 28 DemoImpl d=new DemoImpl(); 29 //接口的三种打印方式 30 System.out.println(d.NUM); 31 System.out.println(DemoImpl.NUM); 32 System.out.println(Demo.NUM); 33 } 34 } 35
5.2 接口的特点
1.接口中成员都是公共的权限,权限都是最大的。
2.接口与接口之间是继承关系,且可以多继承。
3.类与类之间是继承关系(extends),类与接口之间是实现关系(implements)
4.接口不可以实例化,只能由实现了接口的子类并覆盖了接口中所有的抽象方法后,该类才可以实例化,否则,这个子类就是一个抽象类。
5.3 接口的重要体现
解决多继承的弊端,Java将多继承这种机制通过多实现完成(接口中的功能没有方法体,由子类来明确,所以实现了多实现)。
【多实现】
【基于接口的扩展】
【接口与接口之间是继承关系,且可以多继承】
接口避免了单继承的局限性,父类中定义的事物的基本功能,接口中定义事物的扩展功能,一个类可以实现多个接口。
InterfaceDemo2
1 //没有抽象方法的抽象类的由来 2 /* 3 抽象类中是可以不定义抽象方法,仅是不让该类创建对象 4 */ 5 6 interface Inter 7 { 8 void show1(); 9 void show2(); 10 void show3(); 11 void show4(); 12 } 13 /* 14 //定义子类,需要显示show1方法 15 class InterImpl1 implements Inter 16 { 17 //覆盖show1方法 18 public void show1() 19 { 20 System.out.println("show1 run"); 21 } 22 //覆盖其他三个方法,让其子类实例化 23 public void show2(){} 24 public void show3(){} 25 public void show4(){} 26 } 27 28 //另一个子类需要显示show3方法 29 class InterImpl3 implements Inter 30 { 31 //覆盖show1方法 32 public void show3() 33 { 34 System.out.println("show3 run"); 35 } 36 //覆盖其他三个方法,让其子类实例化 37 public void show1(){} 38 public void show2(){} 39 public void show4(){} 40 } 41 */ 42 43 /* 44 问题: 45 使用接口中的部分方法,而覆盖全部方法且每个子类重复做,复用性差 46 47 封装: 48 将这些不用的方法单独抽取到一个独立类中, 49 让这个类去实现接口,并覆盖接口中所以方法。 50 51 */ 52 class InterImpl implements Inter 53 { 54 //实现Inter接口中所有的show方法 55 public void show1(){} 56 public void show2(){} 57 public void show3(){} 58 public void show4(){} 59 } 60 //子类继承InterImpl实现类,实现覆盖show1方法 61 class InterImpl1 extends InterImpl 62 { 63 public void show1() 64 { 65 System.out.println("show1 run"); 66 } 67 } 68 //另一个子类需要显示show3方法 69 class InterImpl3 extends InterImpl 70 { 71 public void show3() 72 { 73 System.out.println("show3 run"); 74 } 75 } 76 class InterfaceDemo2 77 { 78 public static void main(String[] args) 79 { 80 InterImpl1 in1=new InterImpl1(); 81 in1.show1(); 82 InterImpl3 in3=new InterImpl3(); 83 in3.show3(); 84 85 } 86 }
代码的优化、提高复用性
标签:为什么 数据 种类 问题: 打印 部分 创建对象 eth 分享
原文地址:https://www.cnblogs.com/cao-yin/p/8972989.html