------- android培训、java培训、期待与您交流! ----------
--------------------------继承 抽象类 接口 多态
继承extends
提高代码的复用性
继承让类与类产生关系,有了这个关系才有了多态的特性
必须是类与类有所属关系才可以继承,所属:is a
Java不支持多继承,因为多继承存在安全隐患,因为当多个父类中定义了相同的功能,内容相同时,不确定要运行哪个功能。但java保留了这种机制,用另一种形式来完成,叫做多实现implements
Java支持多层继承,也就是一个继承体系。查阅父类功能,创建子类对象使用功能
父类和子类有相同的变量时,
super关键字
用super(父类对象的引用)和 this(本类对象的引用)区分子类父类中变量(当子父类)
当子父类的函数重名时,这个时候运行子类函数,如同父类函数被覆盖
子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败
静态只能覆盖静态
重载:只看同名函数的参数列表
覆盖:子父类方法要一摸一样
子父类的构造函数的特点
在对子类对象进行初始化时,父类的构造函数也会运行
因为子类的构造函数默认第一行有一条隐式的语句super()
super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super()
父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定
super()语句一定要放在子类构造函数的第一行
子类中的构造函数第一行也可以手动指定this()语句来访问本类中的构造函数,子类中至少有一个构造函数会有一个访问父类中的构造函数
final关键字
最终,作为一个修饰符,可以修饰类,变量,函数
被final修饰的类不可以被继承
被final修饰的方法不可以被复写
final可以修饰成员变量,局部变量。被final修饰的变量只能赋值一次,为一个常量。
常量:public static final doublePI = 3.14;
小结:
public classExtendsDemo
{
publicstatic void main(String[] args)
{
Zi z = newZi();
z.show();
}
}
class Fu//若这里加上final,则这个类不能被继承
{
intnum = 9;
Fu()//父的构造函数
{
System.out.println("fu show");
}
void show()//若这里加上final,这这个方法不能被覆盖
{
System.out.println("fu show...."+num);
}
}
class Ziextends Fu
{
Zi()//子的构造函数
{
//这里有个隐式的super();
System.out.println("zi show");
}
void show()//覆盖父类的show方法
{
System.out.println("zi show...."+num);
}
}
打印结果为:
fu show //隐式的super()语句
zi show//子类的构造函数
zi show....9 //覆盖后的show()方法
抽象类
特点:抽象方法一定定义在抽象类中。抽象方法和抽象类都必须被abstract关键字修饰,抽象类不可以new创建对象。抽象类中的方法要被使用,必须用子类复写所有的抽象方法后,建立子类对象调用。
abstract classStudents//抽象类
{
abstractvoid study();//抽象方法1
void write(){}//普通方法
}
模版方法:
在定义功能时,功能的一部分是确定的,另一部分是不确定的。则不确定的那部分用abstract修饰抽象,另一部分用final修饰最终避免被覆盖
abstract class GetTime
{
public final void getTime()//加上final避免被覆盖
{
long start = System.currentTimeMillis();//获取代码开始的时间
runcode();//要被执行的代码
long end = System.currentTimeMillis();//获取代码结束时的时间
System.out.println("毫秒:"+(end - start));
}
public abstract void runcode();//抽象该方法,因为该方法不确定
}
接口
如果抽象类里的抽象方法全部都是抽象的,那么可以将该类用接口的形式来表示
用interface 定义接口
接口中定义常量,抽象方法。
常量用public static final修饰(常量)//可以省略,系统自动补上
方法用public static修饰可以省略,系统自动补上
类与接口之间是实现关系(implements)类与类之间是继承关系(extends)
接口不可以实例化,因为所有方法都是抽象的。必须覆盖全部方法
Interface接口编译之后也生成Java文件
接口支持多实现,是对多继承不支持的转换形式
并且,一个类在继承一个类的同时,可是实现多个接口
接口与接口是继承关系,并且是多继承关系
多态
一种事物的多种表现形态
体现:父类引用指向或者接收子类对象
好处:提高了程序的扩展性
前提:多态的前提是必须是类与类之间有关系,要么是继承,要么是实现,通常存在覆盖
局限性:只能使用父类的引用访问父类中的成员
Animal a =new Cat();//只能使用父类的引用访问父类中的成员
Catc = (Cat)a;//强制将父类的引用,转成子类类型
c.catchMouse();//使用猫的特有方法
判断某一类型的方法 instanceof
多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类是否有调用的方法,如果有,编译通过,没有则编译失败
在运行时期:参阅对象所属的类中是否有调用的方法
成员函数在多态调用时,编译看左边,运行看右边
在多态中,
成员变量的特点:无论编译和运行都参考左边
静态成员函数的特点:无论编译和运行都参考左边(因为静态的方法不属于对象)
总结:
public class DuoTaiDemo
{
public staticvoid main(String[] args)
{
Animal a = newCat();//父类引用指向子类对象
//new Run().Run(a);这里会报错,因为这里a还是父类引用
a.eat();//这里是直接调用主函数里面的eat方法,不会报错
Catc = (Cat)a;//类型提升过程
new Run().run(c);//提升之后可以调用类Run中的方法
}
void eat(Animal a)//传一个动物进来,执行eat()方法
{
a.eat();
}
}
abstract class Animal//animal父类 为抽象类
{
abstrac tvoid eat();
}
class Cat extends Animal
{
void eat()//复写eat方法
{
System.out.println("吃鱼");
}
void catchMouse()//特有方法
{
System.out.println("抓老鼠");
}
}
class Dog extends Animal
{
void eat()//复写eat()方法
{
System.out.println("吃骨头");
}
void kanjia()//特有方法
{
System.out.println("看家");
}
}
class Run//创建一个方法类Run封装动物行为的方法
{
public void run(Animal a)
{
a.eat();
if(ainstanceof Cat)
{
((Cat)a).catchMouse();//强制转换成猫类型调用猫的特有方法
}
else if(a instanceof Dog)
{
((Dog)a).kanjia();//强制转换成狗类型调用狗的特有方法
}
}
}
Object语句
Object类是所有对象的直接或者间接的父类
这个对象定义的是所有对象都具备的功能
equals(Object obj):比较两个对象的内存地址值是否相同(非常重要)
toString()返回该对象的字符串表示:类名@哈希吗值的无符号十六进制
getClass().getName() + '@' +Integer.toHexString(hashCode())
内部类
就是把一个类定义在另一个类里面
好处:
1、可以直接访问外部类的成员,包括私有
2、外部类访问内部类必须建立内部类对象
建立内部类的全名书写:outer.Inner in = new Inner()外部类.内部类对象名 = new 内部类()
内部类访问外部类中的成员变量: outer.this.x
访问格式:
1、 当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象:外部类名.内部类变量名 = new 外部类对象.new 内部类对象;
即:outer.inner in = newouter().new inner;
2、 当内部类定义在成员位置上,就可以被成员修饰符所修饰如:
Private :将内部类在外部类中进行封装
Static :内部类就具备静态的特征(就出现访问局限)
外部其他类中直接访问static内部类中的非静态成员:
new outer.inner.function()
外部其他类中直接访问static 静态内部类的静态成员
outer.inner.function()
当内部类中定义了静态成员,该内部类必须是静态的
当外部类中的静态方法,访问内部类时,内部类也必须是静态的
内部类定义规则:
当描述事物时,事物内部还有事物时,该事物用内部类来描述,因为该内部事物在使用外部事物的内容
内部类定义在局部时,不可以被成员修饰符修饰(static private等)。可以直接访问外部类中的成员。因为还持有外部类中的引用,但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量
匿名内部类
1、 其实就是内部类的简写格式
2、 定义匿名内部类的前提:内部类必须是继承一个类或者实现一个接口
匿名内部类的格式:
new父类或接口(){定义子类的内容}
匿名内部类就是一个匿名子类对象,而且这个对象有点胖。也可以理解为带内容的对象
匿名内部类中的方法最好不要超过3个。超过了就直接继承比较好
public class InnerClassTest
{
public static void main(String[] args)
{
Test.function().method();
/* Test.function():类名直接调用方法说明Test类中有一个静态方法function
*.method():function()这个方法运算后的结果得到一个对象,而且是一个Inter类型的对象
* 因为只有是Inter类型的对象,才能调用method方法*/
}
}
interface Inter
{
void method();
}
class Test
{
static Inter function()//function方法运行后返回一个对象
{
return new Inter()//返回一个Inter类型的子类对象
{
public void method()
{
System.out.println("Inter Run");
}
};//内部类的形式
}
}