Java面向对象三大特征

封装

private关键字

  • 是一个权限修饰符 可以修饰成员
  • 成员变量和成员方法
  • 被private修饰的成员只能在本类中才能访问

针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作

  • 提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰
  • 提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰

this关键字:代表所在类的对象引用

  • 本质:方法被哪个对象调用,this就代表哪个对象
  • 局部变量和成员变量如果重名,Java使用的是就近原则
  • this关键字,可以调用本类的成员(变量, 方法),解决局部变量和成员变量的重名问题

面向对象三大特征:

  • 封装:private只是封装的一种体现
  • 举例1:将代码抽取到方法中,这是对代码的一种封装
  • 举例2:将属性抽取到类当中,这是对数据的一种封装

继承

继承概述:

  • 让类与类之间产生关系(子父类关系),子类可以直接使用父类中的,非私有成员
  • 子类也可称为"派生类",父类也可称为"基类"、“超类”

继承格式:

  • 使用extends关键字
	public class 子类名 extends 父类名{}
  • 特点是:单继承,多层继承,继承具有传递性(例如:爷爷、爸爸、儿子)
  • 继承的访问特点:就近原则(局部,本类,父类)

继承的好处:

  • 提高了代码的复用性
  • 提供了代码的维护性
  • 让类与类之间产生了关系,是多态的前提

继承的弊端:

  • 继承是侵入性的
  • 降低了代码的灵活性:子类必须拥有父类非私有成员,增加了子类的约束
  • 增强了代码之间的耦合性:代码与代码之间的关联称为"耦合性"

继承的应用场景:

  • 当类与类之间,存在相同(共性)内容时

  • 并且产生了"is a"的关系(student is a person、teacher is a person)

  • Java只支持单继承,不支持多继承;但是可以多层继承(形成继承体系)

一个儿子只有一个爸爸(亲的),不能有多个爸爸,爸爸也只有一个爸爸(儿子的爷爷)

Java为什么不支持多继承:

父类中可能存在,同名的成员方法,完成了不同逻辑,如果支持多继承,在子类中造成逻辑混乱
两个爸爸的同名方法,干了不同的事,这时候到底听谁的??

什么是重写?

  • 子类和父类具有两个完全相同的方法(返回值类型,参数列表一致)
  • 四种权限修饰符:(从小到大)private -> 默认 -> protected -> public
    需同时满足的条件
  • 多个方法在同一个类中
  • 多个方法具有相同的方法名
  • 多个方法的参数不相同,类型不同或者数量不同
    方法重写的应用场景:

当子类需要父类功能时,而功能主体子类需要有特有的功能 可以重写父类中的方法,这样既沿袭了父类功能,又定义了子类特有的功能

 public class Phone01 {
    	//一代电话,只能打电话
        public void call(String name){
            System.out.println("给"+name+"打电话");
        }
    }
    public class Phone02 extends Phone01 {
        //二代电话,打电话之前,可以开视频
        @Override
        public void call(String name){
            System.out.println("开启视频功能...");
            //System.out.println("给"+name+"打电话...");
            super.call("吴彦祖");//两种写法都可以
        }
    }
    public class PhoneTest {
        public static void main(String[] args) {
            //创建对象
            Phone01 p1 = new Phone01();
            p1.call("吴彦祖");
            System.out.println("------------------");
            //创建二代对象
            Phone02 p2 = new Phone02();
            p2.call("陈冠希");
        }
    }
方法重写的注意事项
  1. 注意1. 父类中的私有方法不能被重写(父类私有的内容子类访问不到,访问不到就不能重写)
  2. 注意2. 父类静态方法,子类必须通过静态方法"重写";父类非静态方法,子类必须通过非静态方法"重写" 结论:静态不静态,子父类统一
  3. 注意3. 静态方法不能被重写! 强行重写静态方法,子类必须是静态,现象上和重写效果一样,但是本质不同
    可以理解为,子类将父类中的同名方法隐藏,而非重写(从哪看:@Override注解报错)
  4. 注意4. 子类重写父类方法时,访问权限必须大于等于父类方法 public > protected(保护子类) > 默认不写(包权限)> private
  5. 注意5. @Override注解: 位置是,声明在重写父类方法的子类方法上 作用是,检查该方法,重写是否正确,不正确则报错

抽象类:

  • 不能创建对象,用来继承子类强制重写的抽象方法

final关键字的特点:

  1. 类:被final修饰的类为最终类,不能被继承
  2. 方法:最终方法,不能被重写
  3. 变量:会变成常量,命名规则为纯大写(NUM)
  4. 基本数据类型:其值不能被修改
  5. 引用数据类型:地址不能被修改,但是里面的数据可以修改

代码块:

  • 局部代码块
  • 构造代码块(每个构造方法执行前都会先执行)
  • 静态代码块(只执行一次,伴随着类的加载儿运行

多态

什么是多态?

同一个对象,在不同时刻表现出来的不同形态

  • 例如:猫可以叫猫,也可以叫做动物 多态的前提是:要有继承关系、重写方法、父类引用指向子类对象
class Animal {
    public void eat(){
        System.out.println("动物吃饭");
    }
}
class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
public class Test1Polymorphic {
    /*
        多态的前提:

            1. 要有(继承 \ 实现)关系
            2. 要有方法重写
            3. 要有父类引用, 指向子类对象
     */
    public static void main(String[] args) {
        // 当前事物, 是一只猫
        Cat c = new Cat();
        // 当前事物, 是一只动物
        Animal a = new Cat();
        a.eat();
    }
}

成员访问特点:

  • 成员变量:编译看父类,运行看父类
  • 成员方法:编译看父类,运行看子类(因为子类重写父类方法)

多态的好处:

  • 提高程序的扩展性,定义方法的时候,使用父类型作为参数,再使用的时候,使用具体子类型参与操作
  • 弊端:不能使用子类的特有成员

多态中的转型:

  • 向上转型:父类引用指向子类(等同于隐式转换)
  • 向下转型:格式 -> 子类型 对象名 = (子类型)父类引用
class Fu {
    public void show(){
        System.out.println("Fu..show...");
    }
}

class Zi extends Fu {
    @Override
    public void show() {
        System.out.println("Zi..show...");
    }

    public void method(){
        System.out.println("我是子类特有的方法, method");
    }
}

public class Test3Polymorpic {
    public static void main(String[] args) {
        // 1. 向上转型 : 父类引用指向子类对象
        Fu f = new Zi();
        f.show();
        // 多态的弊端: 不能调用子类特有的成员
        // f.method();

        // A: 直接创建子类对象
        // B: 向下转型

        // 2. 向下转型 : 从父类类型, 转换回子类类型
        Zi z = (Zi) f;
        z.method();
    }
}

多态中转型存在的风险和解决方案:

  • 风险:如果被强转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候机会出现ClassCastException
  • 解决方案:关键字 / 格式 -> 变量名 instanceof 类型
    理解:就是判断关键字左边的变量,是否是右边的类型,返回Boolean类型结果
abstract class Animal {
    public abstract void eat();
}

class Dog extends Animal {
    public void eat() {
        System.out.println("狗吃肉");
    }

    public void watchHome(){
        System.out.println("看家");
    }
}

class Cat extends Animal {
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

public class Test4Polymorpic {
    public static void main(String[] args) {
        useAnimal(new Dog());
        useAnimal(new Cat());
    }

    public static void useAnimal(Animal a){  
        a.eat();
        // 判断a变量记录的类型, 是否是Dog
        if(a instanceof Dog){
            Dog dog = (Dog) a;
            dog.watchHome();
        }
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值