第一 封装
一、概述
1、定义:封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
2、好处:
a.将变化隔离
b.便于使用
c.提高重用性
d.提高安全性
3、原则:
a.将不需要对外提供的内容隐藏起来
b.把属性都隐藏,提供公共方法对其访问
4、说明:
a.私有仅仅是封装的一种表现形式,如包也是一种封装形式
b.之所以对外提供访问方式,就是因为可以在访问方式中加入逻辑判断等语句,对访问的数据进行操作,提高了代码的健壮性。
第二 继承
一、概述
当两个事物之间存在一定的所属关系,就像学生和工人都是人,也都具有人的共同特性如姓名等,我们就把人封装成一个类(这个类中存放共性的成员),然后在分别定义学生和工人这两个类中让他们分别继承人这个类,在人与学生和人与工人之间就有了所属关系这种就称为继承,从而学生和工人就具有了人的特性。在java中一个继承的类(为子类)可以从被继承的类(为父类或者超类)中获得一些属性和方法,而不必再自己创建新方法(在不需要复写的情况等)。
二、特点:
1、提高代码复用性,定义在父类中的成员(变量和方法),可以被子类重复使用;
2、让类与类之间产生关系,这样就会有多态的特性。使得应用起来更方便。
需要注意的是:
A.不可以只是为了获取其他类的功能,简化代码就一味的使用继承;必须是类与类之间有所属关系,才可以用继承,这种关系称为“is-a”。
B.java语言中,只支持单继承,不支持多继承。究其原因,是因为多继承容易带来安全隐患:
a.当多个父类中定义了相同的功能,且功能内容不同时,子类对象并不确定要运行哪一个,这就造成了程序的混乱而导致异常出现。
b但是java保留了这种机制,并改良了多继承为多实现,而且接口就可以多继承。
三、使用继承体系中的功能
1、如果使用体系,要先对体系中父类的描述进行参阅,了解父类中的共性功能,即可以使用该体系了。这样既可以减少查阅时间,也能更系统的了解体系结构,以及父类的功能。
2、具体调用父类中的功能的时候,需要创建子类对象,通过子类对象对父类方法调用,实现继承。为何要通过创建子类对象调用父类中的方法呢?原因如下:
a.父类很可能不可以创建对象,如父类是一个抽象类或者接口,这就需要子类创建对象,调用方法。
b.创建子类对象,可以使用更多的功能,如父类公有的,和子类中自定义的特有功能。
单一句话:查阅父类功能,创建子类对象使用功能。
四、子父类出现后,类成员的特点:类成员:变量、函数、构造函数
1、变量:
子父类中出现非私有的同名成员变量是,子类访问本类的同名时,要用this关键字(如果省略了this,仍是代表本类的变量);子类访问父类同名变量时,用super关键字。
补充:this和super两者都存在与方法区中。
this:本类对象引用,那个对象调用this所在的函数,this就代表那个对象。
super:父类对象引用,用于子类初始化父类构造函数、调用父类成员等。
this和super不能同时存在与构造函数中。
2、.函数:(覆盖(重写))
class Fu{
Fu(){
}
void method(){
System.out.println("Fu......");
}
}
class Zi extends Fu{
Zi(){
//super();//隐式的super语句,调用父类中默认的无参构造函数
//子类比有调用父类构造函数的地方,因为子类必须知道父类成员变量的初始化,才能操作其变量
//this和super不能同时存在,因为他们都必须在构造函数的第一行,这是因为他们都是查看构造函数的初始化的
//构造函数不存在重写
}
void method(){//重写,当对象调用时,执行重写后的函数
System.out.println("Zi......");
}
}
重写的应用:
1、当子类继承了父类就沿袭了父类的功能,在子类中虽然具备此功能,但是功能主体却不一样,此时就需要重写父类中的方法,以达到功能扩展的效果。
注意:
1、子类权限必须大于或等于父类权限才能覆盖
2、静态只能覆盖静态,这个一般不用,因为被覆盖后在多态中是静态加载的,容易出问题。
3、构造函数
子类继承了父类也就具备了父类的属性(变量)和功能(方法),所以在加载子类对象之前,子类需要先知道父类构造函数是怎么对其成员变量进行初始化的。也就是因为这样,所以子类的构造函数的第一行都有一条隐式的super();以调用父类的默认的构造函数。如果父类自定义了构造函数,且没有无参的构造函数,这时就需要我们通过super(参数)区自己制定调用父类的构造函数。而且子类必有一个构造函数会访问父类的构造函数。
补充:
因为继承是对封装性的一个极大挑战,所以就引入了final关键字
final:根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变。
final类不能被继承,没有子类,final类中的方法默认是final的。
final方法不能被子类的方法覆盖,但可以被继承。
final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
final不能用于修饰构造方法。
一、概述:
多态:可以理解为事物之间存在多种形态。
如:人有男人和女人。其中男人可以称为男人,也可以称为人
二、多态的体现:
1、父类的引用指向了自己的子类对象
2、父类的引用页可以接受自己的子类对象
如:Person p = new Student();这句话就是在栈内存中产生一个p,然后在堆内存中产生一个Student的对象,然后把Student的对象地址值赋给p,也就是p就指向了Student的对象。
三、多态的前提:
1、必须是类与类之间存在着关系,要么继承、要么覆盖。
2、通常还有一个前提:存在覆盖
四、多态的利弊:
1、好处:大大的提高了程序的扩展性
2、弊端:虽然提高了扩展性,但是只能使用父类的父类的引用访问父类中的成员,不可预先使用子类。这是因为子类在父类之后加载。
Animal a = new Cat();//类型提升,可以调用共性方法
Cat c = (Cat)a;//强转回所属类型,只有这样才能调用子类中特有的方法
注意:
1、不能将父类对象转换成子类类型
2、只有父类引用指向自己子类对象才能转换,可类型提升,也可以强转回子类
3、多态至始至终都是子类在做着变化
abstract class Animal
{
abstract void eat();
}
class Cat extends Animal
{
public void eat()
{
System.out.println("吃鱼");
}
public void catchMouse()
{
System.out.println("抓老鼠");
}
}
class Dog extends Animal
{
public void eat()
{
System.out.println("吃骨头");
}
public void kanJia()
{
System.out.println("看家");
}
}
class Pig extends Animal
{
public void eat()
{
System.out.println("饲料");
}
public void gongDi()
{
System.out.println("拱地");
}
}
//-----------------------------------------
class DuoTaiDemo
{
public static void main(String[] args)
{
//Cat c = new Cat();
//c.eat();
//Dog d = new Dog();
//d.eat();
//Cat c = new Cat();
/*
Cat c1 = new Cat();
function(c1);
function(new Dog());
function(new Pig());
*/
//Animal c = new Cat();
//c.eat();
function(new Cat());
function(new Dog());
function(new Pig());
}
public static void function(Animal a)//Animal a = new Cat();
{
a.eat();
//a.catchMouse();
}
/*
public static void function(Cat c)//
{
c.eat();
}
public static void function(Dog d)
{
d.eat();
}
public static void function(Pig p)
{
p.eat();
}
*/
}
五、多态的特点:
1、成员函数的特点:
编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有编译通过,没有则编译失败。
运行时期:参阅对象所属的类中是否有调用的方法
总结:成员函数在多态调用是,编译时看左边,运行看右边。子类局部有变量就访问局部的,没有就访问子类全局的,子类没有就访问父类的
2、在多态中成员变量和静态的特点:
无论编译和运行都参考左边,即是引用型变量所属的类型。也就是说父类中有就先找父类的。
非静态有重写方法,静态一般不被重写
因为当调用静态方法是,只要建立子类对象,父类与子类的静态方法都会随之加入方法区内存中,这就不需要对象直接可以用类名调用,只要引用还存在,就看引用变量的类型。
六、多态的应用:
1、定义好工具类,就是共同行为封装在一个类中
2、对类型进行抽取-->多态的产生
3、操作同一个大类型,对其中的小类型都可以操作