面向对象的三个特征:封装,继承,多态
封装
封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
好处:将变化隔离,便于使用,提高重用性,提高安全性
Private:私有,权限修饰符,用于修饰类中的成员(成员变量,成员方法)
私有仅仅是封装的一种表现形式,只要权限不在访问的范围内,都是封装
之所以对外提供访问方式,就是因为可以在访问方式中加入逻辑代码,对访问的数据进行操作,提高代码的健壮性
成员变量是在堆内存中(不初始化也能参与运算,因为有默认的初始化值),局部变量在栈内存中(不初始化不能参与运算)
继承
1、 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
继承的特性:
提高代码的复用性
让类与类之间产生了关系,这才有了多态的特性
2、
Java语言中,java只支持单继承,不支持多继承
多继承容易带来安全隐患,当父类中定义了相同函数,子类不确定运行哪一个
但java保留这种机制,并用另外一种体现形式来表示,多实现
Java支持多层继承,也就是一个继承体系,想使用体系,先查阅父类的描述
在具体调用时,要创建子类对象,为什么?
因为一有可能父类不能创建对象,二,子类对象能使用更多的功能
也就是说:查阅父类功能,创建子类对象来使用功能
3、
成员变量是在堆内存中(不初始化也能参与运算,因为有默认的初始化值), 局部变量在栈内存中(不初始化不能参与运算)
构造函数:
特点:函数名和类名一样,不用定义返回值类型,不可以写return语句
对象一建立就会调用与之对应的构造函数,可以用于给对象进行初始化
一个对象的建立,构造函数也就只运行一次
什么时候定义构造函数呢?
当分析事物时,该事物存在一些特性和行为,就可以将这些加入到构造函数里
构造代码块:作用:给对象进行初始化,对象一建立就运行,优先于构造函数执行
和构造函数的区别:构造代码块是给所有对象进行统一的初始化,而构造函数是给对应的对象(构造函数不同来建立的对象)进行初始化
This所表示的对象,类里的成员和函数都是被对象所调用的
This语句:只能用于构造函数之间进行相互调用
This语句只能定义在构造函数的第一行(这是一个规则),this语句相当于初始化动作,所以要先执行这个初始化动作,再执行当前构造函数里自带的初始化动作
Person(String name)
{
this.name = name;
}
Person(String name,int age)
{
this(name);
this.age = age;
}
子父类出现后,类中成员的特点:
类中成员:
1.变量 2 函数 3 构造函数
变量:
如果子类中出现非私有的同名成员变量时,
子类访问本类中的变量使用this,this表示本来对象的引用
子类访问父类中的同名变量使用super,super表示父类对象的引用
子父类中函数的特点 重写(覆盖):
1.子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败
2.静态只能覆盖静态
重载:只看同名函数的参数列表
重写:子父类方法要一模一样
子父类中的构造函数:
在子类给对象进行初始化的时候,会在构造函数里的首行自动加上一个隐式的语句super();会访问父类中空参数的构造函数,如果父类构造函数中没有空参数的构造函数(如果父类中自定义了构造函数,那么默认的空参数构造函数就不会自动生成的了),那么在子类的构造函数中就必须手动指定super语句引用的是父类的哪一个构造函数
为什么子类一定要访问父类中的构造函数?
因为父类中的数据子类可以直接获取,所以在子类对象建立之前,要先看父类是怎么对这些数据进行初始化的
注意:super语句一定定义在子类构造函数第一行
子类的实例化过程:
子类总所有的构造函数,默认都会访问父类中空参数的构造函数,因为子类每一个构造函数内的第一行,都有一个隐身的的super语句,当父类中没有空参数的构造函数时,子类必须手动通过super或者this语句形式来指定访问父类中的构造函数
当然:子类的构造函数第一行也可以收到指定this语句来访问本类中的构造函数,子类中至少会有一个构造函数会访问父类中的构造函数
This和super语句都要放在第一行,因为初始化动作要先做
多态
事物有多种体现形态
1.多态的体现 父类的引用指向自己的子类的对象
2.多态的前提 必须类与类之间有关系(一般还存在着覆盖),要么继承,要么实现,
3.多态的好处 多态的出现提高了程序的扩展性
4.多态的弊端 提高了扩展性,但是父类的引用只能访问父类中的成员
多态的应用
在多态中 非静态成员函数 的特点:(因为是非静态,有重写的概念,才有下面的情况)
在编译时期,参照引用变量所属的类是否有调用方法,有就编译通过
在运行时期,参照对象所属的类中是否有调用方法
总结:成员函数在多态调用时,编译看左边,运行看右边
在多态中, 静态成员函数 的特点:
无论编译和运行,都参考左边
在多态中 成员变量 的特点:
无论编译和运行,都参考左边(引用型变量所属的类),因为父类出现同名变量的时候,会先去找父类的
多态的出现代码中的特点(多态的使用注意事项)
Object 类
Java中所以对象都具备比较性,就是因为Object类中定义了equals方法
Equals比较的就是地址值
一般在类中要进行比较,就要equals,如果要自定义比较功能的话,那可以复写equals方法
类文件对象 Class (它有 getMethods() ,可以获取到这个类中的所有方法,私有也可以获取)
类型转换
Animal a = new Cat();//类型提升,向上转型
Cat c = (Cat)a;//强制将父类引用,转成子类类型,向下转型
c.catchMouse();//这样就可以操作子类的特有数据
// 多态始终都是子类对象在变化
Animal a = new Animal();//假如这样可以创建对象,
Cat c = (Cat)a;//但这样是将父类对象转成子类类型,这样是不可以的
多态的应用
/*
需求:
电脑运行实例
电脑运行基于主板
*/
interface PCI//定义一个接口
{
public void open();
public void close();
}
class MainBoard
{
public void run()
{
System.out.println("mainboard run");
}
public void usePCI(PCI p)//接口型引用指向子类对象,多态
{
if(p!=null)
{
p.open();
p.close();
}
}
}
class NetBoard implements PCI//实现这个接口
{
public void open()//实现接口中的方法
{
System.out.println("NetBoard open");
}
public void close()
{
System.out.println("NetBoard close");
}
}
class SoundBoard implements PCI
{
public void open()
{
System.out.println("SoundBoard open");
}
public void close()
{
System.out.println("SoundBoard close");
}
}
class Demo
{
public static void main(String args[])
{
MainBoard mb = new MainBoard();
mb.run();
mb.usePCI(new NetBoard());//相当于 PCI pci = new NetBoard()
mb.usePCI(new SoundBoard());
}
}