—————————— ASP.Net+Android+IOS开发、.Net培训、期待与您交流!——————————
继承
必须是类与类之间有所属关系,所属关系是:is a (谁是谁中的一员)
比如有学生和工人两个类
将学生和工人的共性部分提取出来,单独描述,只要让学生和工人与
利:
1.提高代码的复用性
2.让类与类之间产生了关系,有了这关系,才有多态的特性
弊:
1.打破了封装性
注意:千万别单纯为了获取其他类的功能简化代码而继承
java中只支持单继承,不支持多继承,因为多继承带来安全隐患,假如情况如下:
当父类中都定义了相当的功能,当功能内容却不同,子类对象不确定要运行哪一个
但是java保留了这种机制,并用另一种体现形式来完成表达,多实现(interface)
java支持多层继承
如何使用一个继承体系的功能?
想要使用体系,先查阅体系父类中描述,因为父类中定义的是体系中的共性功能,
通过了解共性功能,就可以知道该体系的基本功能,那这个体系已经可以基本使用了.
那么在具体调用的时候,要创建最子类的对象,为什么呢?
1.是因为有可能父类不能创建对象
2.创建子类对象可以使用更多的功能,包括基本也包括特有的.
简单一句话:查阅父类的功能,创建子类对象使用功能
聚集:所属关系:has a (谁里面有谁)
集合:例如一个学校,有很多的学生组成(可有可无的)
组合:例如一个有很多的器官组成(必须的)
子类继承父类后类成员的特点:
类中成员:
1.变量
2.函数
3.构造函数
1.变量
如果子类中出现非私有的同名成员变量时,子类要访问本类的变量用this
子类要访问父类中的同名变量用super
super的使用this基本一致
this代表本类对象的引用
super代表父类对象的引用
2.函数
当子类出现与父类非私有一模一样的函数时,当子类对象调用该函数会运行子类函数内容,
如同父类的函数被覆盖一样,这种情况是函数的另一个特性:重写(覆盖)
当子类继承父类,沿袭了父类的功能到子类中,但是子类虽具备了该功能,但是功能
都和父类的不一致,这时,没必要定义新功能,而是使用覆盖,保留父类的功能定义,
并重写功能内容即可.
覆盖:
1.子类覆盖父类,必须保证子类权限大于父类权限才可以覆盖,否则编译失败
2.静态只能覆盖静态
记住:
1.重载:只看同名函数的参数个数,参数类型,与返回值无关
2.重写:父类与子类的函数一模一样,包括返回值
3.构造函数
在对子类进行初始化时,父类的构造函数也会运行,会先于子类构造函数
那是因为子类构造函数有一条隐式的super(),会访问父类中空参数的构造函数
而且子类中所有的构造函数默认第一行都是super();
为什么子类一定要访问父类中的构造函数呢?
因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要下查看父类
是如何对这些数据进行初始化的,所以子类对象初始化时,需要先访问一下父类中的
构造函数,如果要访问父类的指定的构造函数可以通过手动定义super语句方式来指定.
注意:super语句一定只能定义在子类构造函数第一行
结论:子类的所有构造函数默认都会访问父类中的空参数的构造函数,因为
每一个子类构造函数第一行都一条一句隐式的super();
当然父类的构造函数也可以手动指定this来访问本类中构造函数,子类中也
至少会有一个构造函数访问父类中的构造函数.
java中的上帝:超类 object
为什么this和super不能同在一行?
因为他们都只能在第一行
为什么必须在第一行?
因为初始化一定要先做
final关键字
final:最终的 作为一个修饰符
1.可以修饰类,函数,变量
2.被final修饰的类不可以被继承,为了避免被继承,被子类重写功能
3.被final修饰的方法不可以被重写
4.被final修饰的变量是一个常量,只能赋值一次,既可以修饰成员变量也可以修饰局部变量
5.内部类定义在类类中的局部位置上只能访问被final修饰的局部变量
都给这些值起名字,方便与阅读,而这个值不需要改变,所以加上final修饰,
常量所有字母均大写,多单词用_连接
写代码,阅读性很重要.
private不能修饰类
抽象类(abstract class)
当多个类出现相同的功能,但是功能主体不同,这是可以进行向上抽取,
只抽取功能而不抽取功能主体.这时候就可以使用抽象类来描述.
抽象:看不懂 关键字:abstract
抽象类的特点:
1.抽象方法必须定义在抽象类中
2.抽象方法和抽象类都必须使用abstract关键字修饰
3.抽象类不可以用new创建对象,因为创建没意思
4.抽象类的抽象方法被使用,必须有子类复写所有的抽象方法,建立
子类对象使用.如果子类只覆盖了部分,那么该子类就是一个抽象类
事物出现了一些看不懂的东西,不确定的功能定义,但还是需要明确出现
,只是无方法体而已..
抽象类既可以由抽象方法和非抽象方法,抽象方法只能定义在 抽象类中
抽象可以没有抽象方法,这样做仅仅是让该类建立对象而已.
/*
需求:
假如我们开发一个系统时需要对员工进行建模,员工包括了3个属性:
姓名,工号,以及工资,经理也是员工,除了员工的属性外还有一个特有
的提成属性,请使用继承思想设计,需求:类中提供公开的方法进行对外访问
*/
模板设计模式:
什么是模板模式:
在定义功能时,功能部分确定,但有一部分功能不确定,而确定的部分在
使用不确定的部分,那么这时就将不确定的暴露出去,由该类的子类来完成
暴露出去不一定是abstract,也有可能会有初始化内容.
接口(interface)
接口定义时,格式特点:
1.接口中常见定义:常量,抽象方法
2.接口中成员都有固定的修饰符
常量:public static final
方法:public abstract
记住:接口的成员都是public的
类与类是继承关系
类与接口是实现关系
实现接口的关键字:implements
接口是不可以创建对象的,因为存在抽象方法,需要被子类实现,子类是
对接口中的全部覆盖后才可以实例化的,否则子类就是一个抽象类
1.接口是对外暴露的规则
2.接口是程序的功能扩展
3.接口可以被类多实现
4.接口之间可以多继承.
继承
必须是类与类之间有所属关系,所属关系是:is a (谁是谁中的一员)
比如有学生和工人两个类
将学生和工人的共性部分提取出来,单独描述,只要让学生和工人与
单独描述的这个类有关系就可以了.
/*
继承测试类
*/
class Demo1
{
public static void main(String[] args)
{
new Student("学生",15).study();
new Worker("工人",20).work();
}
}
/*人类*/
class Person
{
private String name;
private int 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;
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
}
/*学生 继承 人类*/
class Student extends Person
{
public Student(String name, int age){
super(name,age); //调用父类的构造方法
}
/*学生特有的行为*/
public void study(){
System.out.println(getName()+"学习");
}
}
/*工人 继承 人类 */
class Worker extends Person
{
public Worker(String name, int age){
super(name, age); //调用父类的构造方法
}
/*工人特有行为*/
public void work(){
System.out.println(getName()+"工作");
}
}
利:
1.提高代码的复用性
2.让类与类之间产生了关系,有了这关系,才有多态的特性
弊:
1.打破了封装性
注意:千万别单纯为了获取其他类的功能简化代码而继承
java中只支持单继承,不支持多继承,因为多继承带来安全隐患,假如情况如下:
当父类中都定义了相当的功能,当功能内容却不同,子类对象不确定要运行哪一个
但是java保留了这种机制,并用另一种体现形式来完成表达,多实现(interface)
java支持多层继承
如何使用一个继承体系的功能?
想要使用体系,先查阅体系父类中描述,因为父类中定义的是体系中的共性功能,
通过了解共性功能,就可以知道该体系的基本功能,那这个体系已经可以基本使用了.
那么在具体调用的时候,要创建最子类的对象,为什么呢?
1.是因为有可能父类不能创建对象
2.创建子类对象可以使用更多的功能,包括基本也包括特有的.
简单一句话:查阅父类的功能,创建子类对象使用功能
聚集:所属关系:has a (谁里面有谁)
集合:例如一个学校,有很多的学生组成(可有可无的)
组合:例如一个有很多的器官组成(必须的)
子类继承父类后类成员的特点:
类中成员:
1.变量
2.函数
3.构造函数
1.变量
如果子类中出现非私有的同名成员变量时,子类要访问本类的变量用this
子类要访问父类中的同名变量用super
super的使用this基本一致
this代表本类对象的引用
super代表父类对象的引用
2.函数
当子类出现与父类非私有一模一样的函数时,当子类对象调用该函数会运行子类函数内容,
如同父类的函数被覆盖一样,这种情况是函数的另一个特性:重写(覆盖)
当子类继承父类,沿袭了父类的功能到子类中,但是子类虽具备了该功能,但是功能
都和父类的不一致,这时,没必要定义新功能,而是使用覆盖,保留父类的功能定义,
并重写功能内容即可.
覆盖:
1.子类覆盖父类,必须保证子类权限大于父类权限才可以覆盖,否则编译失败
2.静态只能覆盖静态
记住:
1.重载:只看同名函数的参数个数,参数类型,与返回值无关
2.重写:父类与子类的函数一模一样,包括返回值
3.构造函数
在对子类进行初始化时,父类的构造函数也会运行,会先于子类构造函数
那是因为子类构造函数有一条隐式的super(),会访问父类中空参数的构造函数
而且子类中所有的构造函数默认第一行都是super();
为什么子类一定要访问父类中的构造函数呢?
因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要下查看父类
是如何对这些数据进行初始化的,所以子类对象初始化时,需要先访问一下父类中的
构造函数,如果要访问父类的指定的构造函数可以通过手动定义super语句方式来指定.
注意:super语句一定只能定义在子类构造函数第一行
结论:子类的所有构造函数默认都会访问父类中的空参数的构造函数,因为
每一个子类构造函数第一行都一条一句隐式的super();
当然父类的构造函数也可以手动指定this来访问本类中构造函数,子类中也
至少会有一个构造函数访问父类中的构造函数.
java中的上帝:超类 object
为什么this和super不能同在一行?
因为他们都只能在第一行
为什么必须在第一行?
因为初始化一定要先做
/*
继承后变量, 函数 ,构造函数 的特点 同名
*/
class Demo2
{
public static void main(String[] args)
{
new Zi(50).show();
new Zi(50).method();
}
}
class Fu
{
private int num;
public void setNum(int num){
this.num=num;
}
public int getNum(){
return num;
}
public Fu(){
}
public Fu(int num){
this.num=num;
}
public void method(){
System.out.println("fu...");
}
}
class Zi extends Fu
{
private int num; //父类有的共性,之类不应在有,这是测试
public Zi(){
//一条隐式的父类构造函数
}
public Zi(int num){
//手动指定父类的构造函数
//调用父类的初始化构造函数 子类至少有一个父类的构造函数
super(num);
}
public int getNum(){
return num;
}
/*输出num*/
public void show(){
//也是调用父类的getNum 获取父类的num
//子类重写getNum 才是调用子类的num
System.out.println(getNum());
//需要调用父类的,用super关键字 这才是父类的
System.out.println(super.getNum());
}
/*与父类的同名时 权限等于或大于父类才能覆盖 输出子类的*/
/*当父类的成员为 private 不存在重写 因为不被继承*/
public void method(){
System.out.println("zi...");
}
}
final关键字
final:最终的 作为一个修饰符
1.可以修饰类,函数,变量
2.被final修饰的类不可以被继承,为了避免被继承,被子类重写功能
3.被final修饰的方法不可以被重写
4.被final修饰的变量是一个常量,只能赋值一次,既可以修饰成员变量也可以修饰局部变量
5.内部类定义在类类中的局部位置上只能访问被final修饰的局部变量
都给这些值起名字,方便与阅读,而这个值不需要改变,所以加上final修饰,
常量所有字母均大写,多单词用_连接
写代码,阅读性很重要.
/*
final 关键字
*/
class Demo3
{
//final static 一起用就是共享的固定的数值 例如PI 全部字母大写
//多单词用下_连接
final static double PI=3.14;
public static void main(String[] args)
{
PI=30; //final修饰的变量也是不可修改的
}
}
/*
//final 用于类
final class A
{
}
class B extends A //错误的 被final修饰的类无法继承
{
}
*/
//final 用于函数
class F
{
public final void method(){
//static int d=10; 函数不能定义static
//final int d=10; 函数内可以定义final
System.out.println("fu");
}
} /*
class Z extends F
{
public void method(){ //无法覆盖父类的method,父类的被final修饰了
System.out.println("zi");
}
}
*/
private不能修饰类
抽象类(abstract class)
当多个类出现相同的功能,但是功能主体不同,这是可以进行向上抽取,
只抽取功能而不抽取功能主体.这时候就可以使用抽象类来描述.
抽象:看不懂 关键字:abstract
抽象类的特点:
1.抽象方法必须定义在抽象类中
2.抽象方法和抽象类都必须使用abstract关键字修饰
3.抽象类不可以用new创建对象,因为创建没意思
4.抽象类的抽象方法被使用,必须有子类复写所有的抽象方法,建立
子类对象使用.如果子类只覆盖了部分,那么该子类就是一个抽象类
/*
抽象类测试
*/
class Demo4
{
public static void main(String[] args)
{
//new Test1(); //抽象类不能实例化(new)
new Test2(88).method();
}
}
/*
//错误 抽象方法只能在抽象类里
class Test1
{
public abstract void method();
}
*/
/*
抽象类与其他类描述一样 可以有成员,构造函数 只是多了不确定的部分
*/
abstract class Test1
{
private int num;
public void setNum(int num){
this.num=num;
}
public int getNum(){
return num;
}
public Test1(){
}
public Test1(int num){
this.num=num;
}
public abstract void method();
public void show(){
System.out.println("absctract ");
}
}
/*子类要全部重写父类的抽象方法,否则子类就是抽象类 不能实例化*/
class Test2 extends Test1
{
public Test2(int num){
super(num);
}
/*重写父类的method*/
public void method(){
System.out.println(getNum());
}
}
事物出现了一些看不懂的东西,不确定的功能定义,但还是需要明确出现
,只是无方法体而已..
抽象类既可以由抽象方法和非抽象方法,抽象方法只能定义在 抽象类中
抽象可以没有抽象方法,这样做仅仅是让该类建立对象而已.
/*
需求:
假如我们开发一个系统时需要对员工进行建模,员工包括了3个属性:
姓名,工号,以及工资,经理也是员工,除了员工的属性外还有一个特有
的提成属性,请使用继承思想设计,需求:类中提供公开的方法进行对外访问
*/
/*
需求: 开发一个系统,对员工进行建模,员工有三个属性:姓名,年龄,工资
经理也是员工,除了特点的属性还有一个提成属性, 请用继承思想实现
对外提供访问属性方法
*/
class Demo5
{
public static void main(String[] args)
{
new Worker("张三",15,2222).work();
new Manager("李四",15,1111111,11).work();
}
}
abstract class Employee
{
private String name;
private int age;
private double salary;
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;
}
public void setSalary(double salary){
this.salary=salary;
}
public double getSalary(){
return salary;
}
public Employee(String name, int age, double salary){
this.name=name;
this.age=age;
this.salary=salary;
}
//由于向上提取 都是工作功能定义相同,但内容不同 定义为抽象
//让继承的子类必须实现
public abstract void work();
}
/*工人*/
class Worker extends Employee
{
public Worker(String name, int age, double salary){
super(name,age,salary);
}
public void work(){
System.out.println(getName()+"工人");
}
}
/*经理*/
class Manager extends Employee
{
private double tiCheng;
public void setTiCheng(double tiCheng){
this.tiCheng=tiCheng;
}
public double getTiCheng(){
return tiCheng;
}
public Manager(String name, int age, double salary,double tiCheng){
super(name, age, salary);
this.tiCheng=tiCheng;
}
public void work(){
System.out.println(getName()+"经理");
}
}
模板设计模式:
什么是模板模式:
在定义功能时,功能部分确定,但有一部分功能不确定,而确定的部分在
使用不确定的部分,那么这时就将不确定的暴露出去,由该类的子类来完成
暴露出去不一定是abstract,也有可能会有初始化内容.
/*
模板设计模式
获取一段程序的运行时间
*/
class Demo6
{
public static void main(String[] args)
{
System.out.println("毫秒"+new T().getTime());
System.out.println("毫秒"+new T1().getTime());
}
}
/*
一部分确定的功能就是获取程序运行时间
不确定的就是要运行的程序 abstract
*/
abstract class Program
{
/*程序确定的部分不能修改 用final*/
public final long getTime(){
long start=System.currentTimeMillis();
want();
long end=System.currentTimeMillis();
return end-start;
}
public abstract void want();
}
/*
只要继承 子类重写want() 调用父类的getTime()就可以 获取want()功能的运行时间
*/
class T extends Program
{
public void want(){
for (int i=0;i<1000 ;i++ )
{
System.out.print(i);
}
}
}
/*
再来求一个程序的运行时间
*/
class T1 extends Program
{
public void want(){
int i=0;
while(i<4000){
System.out.print(i);
i++;
}
}
}
接口(interface)
接口定义时,格式特点:
1.接口中常见定义:常量,抽象方法
2.接口中成员都有固定的修饰符
常量:public static final
方法:public abstract
记住:接口的成员都是public的
类与类是继承关系
类与接口是实现关系
/*
接口测试类
*/
class Demo7
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
/*final 不能修饰接口*/
interface Inter
{ /*
接口没有构造函数
public Inter(){
}
*/
//int a;//接口不能有变量
//接口常定义常量,抽象方法
public final static double PI=3.14;
/*讲话*/
public abstract void speak();
}
/*
//接口可以多继承,多实现 错误演示
interface A
{
public abstract void show();
}
interface B
{
public abstract int show();
}
interface C extends A,B //多继承
{
//继承的时候两个相同的show jvm不知道调用那个 会报错
//这是不能有同名show方法(包括返回值类型相同)
}
*/
//接口可以多继承,多实现
interface A
{
public abstract void show();
}
interface B
{
public abstract int method();
}
interface C extends A,B //多继承
{
public abstract void eat();
}
class One implements Inter,C //多实现
{
public void show(){}
public int method(){
return -1;}
public void eat(){
}
public void speak(){
}
}
实现接口的关键字:implements
接口是不可以创建对象的,因为存在抽象方法,需要被子类实现,子类是
对接口中的全部覆盖后才可以实例化的,否则子类就是一个抽象类
1.接口是对外暴露的规则
2.接口是程序的功能扩展
3.接口可以被类多实现
4.接口之间可以多继承.
接口与类的所属关系是: like a (你像谁中的一个)
class Demo8
{
public static void main(String[] args)
{
new Pupil("z",15).study();
new MidStu("d",157).study();
}
}
abstract class Student
{
private String name;
private int 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;
}
public Student(String name, int age){
this.name=name;
this.age=age;
}
/*学习内容不确定*/
public abstract void study();
}
/*小学生*/
class Pupil extends Student//Pupil
{
public Pupil(String name, int age){
super(name,age);
}
public void study(){
System.out.println("小学生学习小学内容");
}
}
/*
接口是对外暴露的规则
接口是程序的扩展功能
*/
interface Smok
{
public abstract void smoking();
}
/*中学生*/
class MidStu extends Student implements Smok
{
public MidStu(String name, int age){
super(name,age);
}
public void study(){
System.out.println("中学生学习中学内容");
}
public void smoking(){
System.out.println("中学生还会抽烟 ");
}
}
—————————— ASP.Net+Android+IOS开发、.Net培训、期待与您交流!——————————