面向对象的三大特征

封装

就是把抽象的数据【属性】和对数据的操作【方法】封装在一起,数据被保护在内部,程序的其他部分只有通过授权的操作【方法】才能对数据进行操作

封装的实现步骤

1、将属性私有化 private

2、提供一个公共的(public)set方法,用于对属性判断并赋值

​ public void setXxx(类型 参数名){

​ // Xxx表示某个属性

//	加入数据验证的业务逻辑

​ 属性=参数名

​ }

3、提供一个公共的(public)get方法,用于获取属性的值

​ public 数据类型 getXxx(){

​ //增加权限判断

​ return Xxx

​ }

封装验证
1、普通验证

创建无参构造器,调用set方法验证

		Person person = new Person();
        person.setName("大");
        person.setAge(18);
        System.out.println(person.info());
        
          public Person(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name.length() >= 2 && name.length() <= 6) {
            this.name = name;
        } else {
            System.out.println("你设置的名字长度不合理,默认名字天美");
            this.name = "天美";
        }
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age >= 1 && age < 120) {
            this.age = age;
        } else {
            System.out.println("你设置的年龄不合理,默认年龄8");
            this.age= 8;
        }

    }

2、将构造器和set方法结合在初始化对象的时候进行验证

 Person person = new Person("1", 118, 2326);
 System.out.println(person.info());
 
     public Person(String name, int age, double salary) {
//        this.name = name;
//        this.age = age;
//        this.salary = salary;
        setName(name);
        setAge(age);
        setSalary(salary);
    }
    
      public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name.length() >= 2 && name.length() <= 6) {
            this.name = name;
        } else {
            System.out.println("你设置的名字长度不合理,默认名字天美");
            this.name = "天美";
        }
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age >= 1 && age < 120) {
            this.age = age;
        } else {
            System.out.println("你设置的年龄不合理,默认年龄8");
            this.age= 8;
        }

    }

继承

继承作用

当两个类的部分属性和方法相同时,使用继承,可以解决代码的复用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dFTXFtvb-1680138080440)(C:\Users\27310\AppData\Roaming\Typora\typora-user-images\image-20230130104824010.png)]

继承的基本语法

class 子类 extends 父类{

1、子类会自动拥有父类定义的属性和方法

2、父类又叫超类,基类

3、子类又叫派生类

}

继承的注意事项及使用细节

1、子类继承了所有的属性和方法,非私有的属性和方法可以直接访问,私有的属性和方法需要通过父类提共的公共方法进行访问

2、子类最多只能继承一个父类(直接继承),即java是单继承机制

构造器调用的具体细节

1、继承了之后,子类必须调用父类的构造器,完成父类的初始化

2、如果希望指定去调用父类的构造器,super(参数列表)

3、super 只能在构造器中使用

4、构造器的调用只能放在构造器里面的第一条语句上,

5、父类构造器的调用不限于直接父类,会一直追溯到Object类(顶级父类)

6、构造器在对象初始化的时候被调用,当初始化有参构造器时,无参构造器会被顶替掉,此时系统不会自动调用无参构造器

1、初始化的是无参构造器
public class TextExtends02 {
    public static void main(String[] args) {
        Sub sub = new Sub();
    }
}

class TopBase {//父类的父类的Object

    public TopBase() {
        System.out.println("构造器TopBase被调用");
    }
}

class Base extends TopBase {
   
    public Base() {
        System.out.println("父类中的Base()构造器被调用...");
    }

    public Base(String name, int age) {
        System.out.println("父类的Base(String name, int age)被调用");
    }

    public Base(String name) {
        System.out.println("父类的Base(String name)被调用");
    }



class Sub extends Base {
    public Sub(String name, int age) {
        //希望调用父类中的无参构造器
        super("大黄", 45);
        System.out.println("子类中的(String name,int age)被调用");
    }

    public Sub() {
        super();
        System.out.println("子类中的Sub()构造器被调用");
    }

    public Sub(String name) {
        super("大狗", 30);
        System.out.println("子类中的Sub(String name)构造器被调用");
    }

    public void sayOk() {//子类中的方法
        System.out.println(n1 + " " + n2 + " " + n3);
        test100();
        test200();
        test300();
        //提供的特有方法去访问
        System.out.println("n4" + getN4());
        callTest400();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nTpGHLTv-1680138080441)(C:\Users\27310\AppData\Roaming\Typora\typora-user-images\image-20230130113350616.png)]

2、初始化的是一个参数的构造器

此时,调用了Sub的一个参数的构造器,这个构造器中,利用 super(“大狗”, 30)调用到了父类的两个参数的构造器,有参构造器顶替掉了无参构造器,所以系统不会调用Base的无参构造器

public class TextExtends02 {
    public static void main(String[] args) {
        Sub sub1 = new Sub("jack");
    }
}

class TopBase {//父类的父类的Object

    public TopBase() {
        System.out.println("构造器TopBase被调用");
    }
}

class Base extends TopBase {
   
    public Base() {
        System.out.println("父类中的Base()构造器被调用...");
    }

    public Base(String name, int age) {
        System.out.println("父类的Base(String name, int age)被调用");
    }

    public Base(String name) {
        System.out.println("父类的Base(String name)被调用");
    }

class Sub extends Base {
    public Sub(String name, int age) {
        //希望调用父类中的无参构造器
        super("大黄", 45);
        System.out.println("子类中的(String name,int age)被调用");
    }

    public Sub() {
        super();
        System.out.println("子类中的Sub()构造器被调用");
    }

    public Sub(String name) {
        super("大狗", 30);
        System.out.println("子类中的Sub(String name)构造器被调用");
    }

    public void sayOk() {//子类中的方法
        System.out.println(n1 + " " + n2 + " " + n3);
        test100();
        test200();
        test300();
        //提供的特有方法去访问
        System.out.println("n4" + getN4());
        callTest400();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u9d2bc2u-1680138080442)(C:\Users\27310\AppData\Roaming\Typora\typora-user-images\image-20230130113634678.png)]

3、初始化的是两个参数的构造器

此时,调用了Sub的两个参数的构造器,这个构造器中,利用 super(“大黄”, 45)调用到了父类的两个参数的构造器,有参构造器顶替掉了无参构造器,所以系统不会调用Base的无参构造器

public class TextExtends02 {
    public static void main(String[] args) {
       Sub sub2 = new Sub("jack", 45);
    }
}

class TopBase {//父类的父类的Object
    public TopBase() {
        System.out.println("构造器TopBase被调用");
    }
}

class Base extends TopBase {
    
    public Base() {
        System.out.println("父类中的Base()构造器被调用...");
    }
    
    public Base(String name, int age) {
        System.out.println("父类的Base(String name, int age)被调用");
    }
    
    public Base(String name) {
        System.out.println("父类的Base(String name)被调用");
    }
    
class Sub extends Base {
    public Sub(String name, int age) {
        //希望调用父类中的无参构造器
        super("大黄", 45);
        System.out.println("子类中的(String name,int age)被调用");
    }

    public Sub() {
        super();
        System.out.println("子类中的Sub()构造器被调用");
    }

    public Sub(String name) {
        super("大狗", 30);
        System.out.println("子类中的Sub(String name)构造器被调用");
    }

    public void sayOk() {//子类中的方法
        System.out.println(n1 + " " + n2 + " " + n3);
        test100();
        test200();
        test300();
        //提供的特有方法去访问
        System.out.println("n4" + getN4());
        callTest400();
    }
}

继承后,父类的属性和方法的访问

子类继承父类后,会继承父类所有的属性和方法,在访问时,子类可以直接访问父类非私有的属性和方法,私有的属性和方法需要通过调用父类提供的公开的方法进行访问

public class TextExtends02 {
    public static void main(String[] args) {
        Sub sub = new Sub();
        sub.sayOk();
    }
}
class Base extends TopBase {
    //四个属性
    public int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    private int n4 = 400;
    //特有的方法
    public int getN4() {
        return n4;
    }

    public void test100() {
        System.out.println("test100");
    }

    protected void test200() {
        System.out.println("test200");
    }

    void test300() {
        System.out.println("test300");
    }

    private void test400() {
        System.out.println("test400");
    }

    //特有的方法
    public void callTest400() {
        test400();
    }
}

class Sub extends Base {
    public void sayOk() {//子类中的方法
        System.out.println(n1 + " " + n2 + " " + n3);
        test100();
        test200();
        test300();
        //提供的特有方法去访问
        System.out.println("n4" + getN4());
        callTest400();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EjkEa00q-1680138080443)(C:\Users\27310\AppData\Roaming\Typora\typora-user-images\image-20230130114635584.png)]

继承机制的本质

当子类调用属性或者方法时,按照查找关系返回信息

1、如果子类有该属性或者方法,如果子类有,并且可以直接访问,返回信息

2、如果子类没有这个属性,看父类有没有(父类有,并且可以直接访问,返回信息)

3、如果父类没有,按照 2 的规则继续寻找上级父类,直到Object

public class ExtendsTheory {
    public static void main(String[] args) {
        Son son = new Son();
        System.out.println(son.name);
        System.out.println(son.getAge());
        System.out.println(son.hobby);
    }
}

class GrandPa {//爷爷类
    String name = "大头爷爷";
    String hobby = "旅游";
}

class Father extends GrandPa {//父类
    String name = "大头爸爸";
    private int age = 37;

    public int getAge() {
        return age;
    }
}

class Son extends Father {//子类
    String name = "大头儿子";
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RnxeaG1j-1680138080443)(C:\Users\27310\AppData\Roaming\Typora\typora-user-images\image-20230130115249360.png)]

多态

1、方法的多态
重写和重载提现多态

重载:通过传入不同的参数,从而调用不同的方法

重写:调用不同类中的方法,实现不同的功能

   public static void main(String[] args) {
        //方法的重载体现多态
        A a = new A();
        //这里我们传入不同的参数,调用不同的sum方法,就体现多态
        System.out.println(a.sum(10, 20));
        System.out.println(a.sum(10, 20, 30));
        a.say();
        //方法的重写也体现了多态
        B b = new B();
        b.say();
    }
}

class B {//父类

    public void say() {
        System.out.println("B类中的say()方法被调用");
    }
}

class A extends B {//子类

    public int sum(int n1, int n2) {
        return n1 + n2;
    }

    public int sum(int n1, int n2, int n3) {
        return n1 + n2 + n3;
    }

    public void say() {
        System.out.println("A类中的say()方法被调用");
    }
}
2、对象的多态

1、一个对象的编译类型和运行类型可以不一致

2、编译类型在定义对象的时候,就确定了,不能改变

3、运行类型是可以改变的

4、编译类型看=号的左边 运行类型看=号的右边

多态的注意事项和细节讨论

多态的前提是:两个对象(类存在继承关系)

多态的向上转型

本质:父类的引用指向了子类的对象

语法:父类类型 引用名 = new 子类类型();

特点:

1、可以调用父类的所有成员(访问权限)

2、不能调用子类的特有成员、因为在编译阶段能调用哪一些成员,是由编译类型决定的

3、最终的运行效果看子类(运行类型)的具体实现,

调用方法的时候,按照从子类(运行类型)开始查找方法,然后调用

public static void main(String[] args) {
        Animal02 animal02 = new Cat02();
        Object object = new Cat02();
        animal02.run();
        animal02.eat();
        animal02.show();
        animal02.sleep();
//        animal02.catMouse();
    }
}

class Animal02 {
    String name = "动物";
    int age = 10;

    public void sleep() {
        System.out.println("睡");
    }

    public void run() {
        System.out.println("跑");
    }

    public void eat() {
        System.out.println("吃");
    }

    public void show() {
        System.out.println("hello 你好");
    }
}

class Cat02 extends Animal02 {
    public void eat() {
        System.out.println("猫吃鱼的方法");
    }

    public void catMouse() {
        System.out.println("猫抓老鼠");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PANg87J8-1680138080444)(C:\Users\27310\AppData\Roaming\Typora\typora-user-images\image-20230201113359231.png)]

多态的向下转型(解决向上转型不能调用子类特有的方法)

调用子类特有的方法

语法:子类类型 引用名= (子类类型) 父类引用

1、只能强转父类的引用,不能强转父类的对象

2、父类的引用必须指向的是当前目标类型的对象

3、当向下转型后,可以调用子类类型中的所有成员

    Animal02 animal02 = new Cat02();
//        Cat02 cat02=(Cat02)  animal02;
//        cat02.catMouse();
        //一步到位
        ((Cat02) animal02).catMouse();
    }
}

class Animal02 {
    String name = "动物";
    int age = 10;

    public void sleep() {
        System.out.println("睡");
    }

    public void run() {
        System.out.println("跑");
    }

    public void eat() {
        System.out.println("吃");
    }

    public void show() {
        System.out.println("hello 你好");
    }
}

class Cat02 extends Animal02 {
    public void eat() {
        System.out.println("猫吃鱼的方法");
    }

    public void catMouse() {
        System.out.println("猫抓老鼠");
    }
}

class Dog02 extends Animal02 {
}
属性没有重写之说!属性值看编译类型
public class PolyDetail02 {
    public static void main(String[] args) {
//        属性没有重写之说!属性的值看编译类型
        Base base=new Sub();//向上转型
        System.out.println(base.count);
        Sub sub=new Sub();
        System.out.println(sub.count);
    }
}

class Base {
    //父类
    int count = 0;
}

class Sub extends Base {
    //子类
    int count = 20;
}

");
}
}

class Cat02 extends Animal02 {
public void eat() {
System.out.println(“猫吃鱼的方法”);
}

public void catMouse() {
    System.out.println("猫抓老鼠");
}

}

class Dog02 extends Animal02 {
}


#### 属性没有重写之说!属性值看编译类型

```java
public class PolyDetail02 {
    public static void main(String[] args) {
//        属性没有重写之说!属性的值看编译类型
        Base base=new Sub();//向上转型
        System.out.println(base.count);
        Sub sub=new Sub();
        System.out.println(sub.count);
    }
}

class Base {
    //父类
    int count = 0;
}

class Sub extends Base {
    //子类
    int count = 20;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dgIyXazU-1680138080444)(C:\Users\27310\AppData\Roaming\Typora\typora-user-images\image-20230201114132466.png)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值