3.1 面向对象特点
特点
**封装:**将类中不需要对外开放的接口隐藏起来。
**继承:**子类可继承父类的公有成员变量和成员函数。
**多态:**同一个行为具有多个不同表现形式或形态的能力。
对象:对象是一个类的具体实例
语法
/**
描述手机
静态属性:颜色,品牌,尺寸。。。
动态属性:打电话
*/
class Phone{
String color;//颜色
String brand;//品牌
double size;//尺寸
void call(){
System.out.println("打电话");
}
}
class PhoneDemo{
public static void main(String[] args){
Phone p = new Phone();//创建了一个电话对象
p.color = "黑色";
p.brand = "华为";
p.size = 5.5;
System.out.println(p.color);
System.out.println(p.brand);
System.out.println(p.size);
p.call();//调用类中成员函数时 语法:对象名 . 函数变量名
}
}
3.2 类内存图
3.3 成员变量与局部变量
成员变量与局部变量的区别
成员变量 | 局部变量 | |
---|---|---|
位置 | 类中,方法(函数)外 | 方法(函数)中或者方法声明上(形参) |
生命周期 | 与对象共存亡 | 与方法(函数)共存亡 |
初始值 | 有默认值String =null,double= 0.0int= 0 | 没有默认值 须先定义,赋值,后使用 |
class Var{
int x;//成员变量
public void show(){
int y = 5;//局部变量
System.out.prinlnt(x);
System.out.prinlnt(y);
}
}
class VarDemo{
public static void main(String[] args){
Var v = new Var();
v.show();
}
}
3.4 封装
封装:是指隐藏对象的属性和细节,仅对外提供公共访问方式
封装的优点
- 将变化隔离
- 便于使用
- 提高重用性
- 提高安全性
封装的原则
- 降不需要对外提供的内容都隐藏起来
- 把属性都隐藏,提供公共方法对其访问
3.5 继承
继承基本概念:
含义
当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为只要继承这个类即可(将多个类之间的共性进行抽取,抽取出一个单独类,出处类再继承抽取出的类,提高代码复用性)
父类含义
多个类成为子类,单独的这个类称为父类(超类或者基类)
语法格式
Class A extends B{}
作用
提高代码复用性。 让类与类之间产生了关系,为多态提供了前提。
与C++不同
Java只支持单继承不支持多继承,支持多层继承
继承中成员变量特点
class Fu{
int age = 45;
void talk(){
System.out.println("爸爸会讲中文......");
}
}
class Zi extends Fu{
int age = 18;
void show(){
System.out.println(super.age);
}
void talk(){
System.out.println("儿子会讲中文......");
}
}
class ExtendsDemo1{
public static void main(String[] args){
Zi zi = new Zi();
zi.talk();
}
}
继承中成员函数特点
继承中成员函数的特点
方法的重写:发生在子父类中
方法的重载:发生在一个类中
class Fu{
int age = 45;
Fu(){
super();
talk();
System.out.println("父类构造函数......");
}
void talk(){
System.out.println("爸爸会讲中文......");
}
}
class Zi extends Fu{
int age = 18;
Zi(){
//super();//super和this,只能存在一个
System.out.println("子类构造函数......");
return;
}
Zi(int age){
this.age = age;//This 是指向本类的指针
}
void show(){
System.out.println(super.age);
return;
}
void talk(){
System.out.println("儿子会讲中文......");
}
}
class ExtendsDemo2{
public static void main(String[] args){
new Zi();//没有名字的对象,匿名对象
}
}
方法重写
子类中出现与父类一模一样的方法时,会出现覆盖操作,也成为重写或者覆盖
重写覆盖注意:
重写方法是必须和被重写方法具有相同的方法名称,参数列表和返回值类型。 覆盖时,子类方法权限一定要大于等于父类方法权限()
静态只能覆盖静态。 父类中的私有方法不可以被覆盖。
子类的实例化过程
子类中所有的构造函数默认都会访问父类中空参数的构造函数,因为每一个构造函数的第一行都有一条默认的语句super();
子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。
当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数。
/**
子类对象调用时,会调用父类的构造函数,super语句
计算机会默认添加并调用父类默认构造函数,若要调用
父类有参构造函数,需要特别写出super(参数)
*/
class Fu{
int age = 45;
Fu(){
super();
talk();
System.out.println("父类构造函数......");
}
void talk(){
System.out.println("爸爸会讲中文......");
}
}
class Zi extends Fu{
int age = 18;
Zi(){
//super();//super和this,只能存在一个
System.out.println("子类构造函数......");
return;
}
Zi(int age){
this.age = age;
}
void show(){
System.out.println(super.age);
return;
}
void talk(){
System.out.println("儿子会讲中文......");
}
}
class ExtendsDemo2{
public static void main(String[] args){
new Zi();//没有名字的对象,匿名对象
}
}
子类对象实例化过程(文字描述 大概)
Main函数进栈New Zi 堆内子类中有一个父类空间 方法区子父类函数加载
调用new 构造对象Zi Zi类构造函数进栈
super调用父类构造函数
(父类构造函数进栈)
调用talk (talk函数进栈)(talk函数出栈)
(父类构造函数出栈))
(super执行完 子类构造函数执行完毕 出栈)main函数执行完毕出栈
子类对象实例化过程(图描述 大概)
3.6 多态
含义:
相同的消息发给不同的对象而引发不同的行为
字面意思就是多种形态:
- Java中表现形式: fu f = new Zi();
- 父类或接口中的引用指向子类对象
优点:
- 提高了程序的扩展性和后期可维护性
多态前提
- 需要存在继承或实现关系
- 要有覆盖操作
自动类型提升
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("小狗汪汪吃饭...");
}
}
class DuotaiDemo{
public static void main(String[] args){
//Cat c = new Cat();
//c.eat();
Animal a = new Cat();// 自动类型提升的问题
//限制了对猫的特有功能的访问
//专业说法:向上转型,将子类特有的方法隐藏,不能使用子类特有的方法
a.eat();
//判断复杂数据类型
if(a instanceof Cat){
Cat c = (Cat)a;//专业说法:向下转型
}
}
}
Animal类型提升至Cat类型
但是限制对象a对cat类特有功能的访问
向上转型,将子类特有方法隐藏 ,不能使用子类特有方法