Java三大特性

Java三大特性

1.封装(encaplusation)

官方解释:在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。

我的理解:1.对数据进行私有化 起到保护作用 外界不能直接访问 2.对数据进行校验

代码

package Encapsulation;
​
import java.util.Scanner;
​
public class A {
   private String name;
   private int age;
​
   Scanner  scanner = new Scanner(System.in);
    public A(String name, int age) {
//        this.name = name;
//        this.age = age;
//      构造器和 setXxx结合
        setName(name);
        setAge(age);
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        if (name.length() <= 6 ) {
            this.name = name;
        } else {
            System.out.println("你输入的名字太长了");
        }
​
    }
​
    public int getAge() {
        System.out.println("请输入您的名字");
        String input_name = scanner.next();
        //权限校验
        if(input_name.equals(input_name)) {
            return age;
        }else  {
            return -1;
        }
​
    }
​
    public void setAge(int age) {
        if (age >= 1 && age <= 150) {
            this.age = age;
        } else  {
            System.out.println("你输入的年龄不符合规定");
        }
​
    }
}
package Encapsulation;
​
public class Encapsulation {
    public static void main(String[] args) {
//        A a = new A("joshua",2000);
        A a = new A("joshua",18);
        System.out.println(a.getAge());
        System.out.println(a.getName());
//        20
//        joshua
​
    }
}
​

2.继承(Inherit)

官方解释:继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过 extends 来声明继承父类即可

我的理解: 子类继承父类 子类 可以减少 代码量 提高代码的复用率

2.1 继承的具体十大细节:

  1. 子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访

    问,要通过父类提供公共的方法去访问

    父类
    public class Animal {
        private String name;
        private double weight;
    ​
        public Animal(String name, double weight) {
    //        this.name = name;
    //        this.weight = weight;
            // this is  encapsulation
            setName(name);
            setWeight(weight);
        }
    ​
        public String getName() {
            return name;
        }
    ​
        public void setName(String name) {
            this.name = name;
        }
    ​
        public double getWeight() {
            return weight;
        }
    ​
        public void setWeight(double weight) {
            this.weight = weight;
        }
    }
    子类
    public class Dog extends Animal {
        //这里一开始会报错是因为 有 super() 会找默认的构造器 父类的构造器哦被覆盖率 没有了 就报错
        //定义 dog 特有 的属性
        private String color;
    ​
        public Dog(String name, double weight,String color) {
            //这里调用父类的构造器哦
            super(name, weight);
    //        this.color = color;
            setColor(color);
        }
    ​
        public String getColor() {
            return color;
        }
    ​
        public void setColor(String color) {
            this.color = color;
        }
    }
    测试
    public class Test {
        public static void main(String[] args) {
            Dog dog = new Dog("汪汪",100,"yellow");
            Pig pig = new Pig("哼哼",300,"pink");
    ​
            //查看属性
            System.out.println(dog.getName()+" "+dog.getWeight()+"  "+ dog.getColor() );
            // 私有化的getColor方法 没有提供public 直接访问就会报错 color' has private access in 'inheritance.Dog'
            //        汪汪 100.0  yellow  下面的pig 不举列子了
        }
    }
    ​

    2.子类必须调用父类的构造器, 完成父类的初始化

    核心代码
    ​
    父类
    ​
        // 默认的constructor
        public Animal() {
            System.out.println("我是父类无参constructor");
        }
    ​
        public Animal(String name) {
            System.out.println("我是父类的有参构造器哦");
        }
        
        子类
        //对应父类的无参constructor
        public Dog() {
            System.out.println("我是子类constructor");
        }
        //有参constructor
        public Dog(String color) {
            super("joshua");//指定调用父类自定义的有参构造器
    //        不指定就会调用父类的无参构造器
            this.color = color;
            System.out.println("我是子类的有参构造器");
        }
        
        测试
    //2.   子类必须调用父类的构造器, 完成父类的初始化
            Dog dog1 = new Dog();
    //        我是父类constructor
    //        我是子类constructor
            System.out.println("=========");
            Dog dog2 = new Dog("blue");
    //        我是父类的有参构造器哦
            我是子类的有参构造器

    3.当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译

    不会通过(怎么理解。) [举例说明

    父类
     // 默认的constructor
        public Animal() {
            System.out.println("我是父类无参constructor");
        }
    ​
        public Animal(String name) {
            System.out.println("我是父类的有参构造器哦");
        }
        
    子类
    public Dog(String color) {
            super("joshua");//指定调用父类自定义的有参构造器
    //        不指定就会调用父类的无参构造器
            this.color = color;
            System.out.println("我是子类的有参构造器");
        }
        
       测试
         Dog dog1 = new Dog();
    //        我是父类constructor
    //        我是子类constructor
            System.out.println("=========");
            Dog dog2 = new Dog("blue");
    //        我是父类的有参构造器哦
            我是子类的有参构造器
    ​
    很上面一样的 哈哈哈 我的理解是 完成子类的初始化 必须要先完成 父类的初始化 现有爸爸 才有儿子嘛
    其中 子类 必须 指定 父类 的 构造器 了 不知道 就是会调用默认的啦  就相当于 儿子 要选择 爸爸 不指定就是默认的爸爸(就是我啦 哈哈哈 坏笑)

    4.如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表) 上面有不说辣

    5.super 在使用时,必须放在构造器第一行

    super语句在 构造器的代码块中的 只能放在 第一行 必须完成对父类的初始化 完成继承

    注意 super() 和 this() 不能同时使用在构造器中 这里 简单说明一下 super() 和 this()

    super("") 直接调用父类的构造器 this("") 先看自己本类有没有 对应的构造器 再去 父类看有没有对应的构造器 、

    6.super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器

    7.java 所有类都是 Object 类的子类, Object 是所有类的基类

    for example String 是 Object 的子类

    8.父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类)

    所有对象初始化的时候会先加载Object 再 加载下面的类

    9.子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。

    思考:如何让 A 类继承 B 类和 C 类? 【A 继承 B, B 继承 C】

    10。 不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系

    父类 person 子类 animal 这是不行的 父类和子类要有逻辑关系

    2.继承的本质

    package inheritance.theory;
    //cv hsp java course 眼ヾ(≧▽≦*)oヾ(≧▽≦*)o
    public class Test {
        public static void main(String[] args) {
            Son son = new Son();//内存的布局
    //?-> 这时请大家注意,要按照查找关系来返回信息
    //(1) 首先看子类是否有该属性
    //(2) 如果子类有这个属性,并且可以访问,则返回信息
    //(3) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
    //(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到 Object...
            System.out.println(son.name);//返回就是大头儿子
    //System.out.println(son.age);//返回的就是 39
    //System.out.println(son.getAge());//返回的就是 39
            System.out.println(son.hobby);//返回的就是旅游
        }
    }
    class GrandPa { //爷类
        String name = "大头爷爷";
        String hobby = "旅游";
    }
    class Father extends GrandPa {//父类
        String name = "大头爸爸";
        private int age = 39;
        public int getAge() {
            return age;
        }
    }
    class Son extends Father { //子类
        String name = "大头儿子";
    }
    ​
    ​

    我的理解: 一开始是从顶级父类Object到父类再到子类 加载的 查找呢 是从 当前类开始查找 没有 向上找 找到为止 找不带就报错了

    3.详解 super 关键字

    1.super 代表父类的引用,用于访问父类的属性、方法、构造器

    2.super. 属性or 方法 可以访问父类的属性和方法 但不能访问父类的private属性

    3.super("") 只能放在构造器的第一行 只能出现一句

    爷爷类
    public class Grandpa {
        public String name = "牛爷爷";
        public int age = 80;
        public String hobby = "fishing";
    ​
        public void test() {
            System.out.println("I am grandpa method");
        }
    }
    ​
    ​
    父类
    public class Father extends Grandpa{
        public String name = "胡英俊";
        public int age = 40;
        public String hobby = "play game";
        private String secret = "hide Private money";
    ​
        public String getSecret() {
            return secret;
        }
        public void test() {
            System.out.println("I am father method");
        }
    }
    儿子类
    public class Son extends Father{
        public String name = "胡图图";
        public int age = 8;
    //    public String hobby = "feed pet";
    //
    //    public void test() {
    //        System.out.println("I am son method");
    //    }
        public void showFather() {
    //        System.out.println(super.name+"  "+super.age +"  "+super.secret());//super不能访问父类 的私有方法和属性
            System.out.println(super.name+"  "+super.age +"  "+super.getSecret());
        }
    ​
        public void  superMethod() {
            super.test();
        }
    ​
        public void  thisMethod() {
           this.test();
        }
    ​
    ​
    }
    ​

    这里区别一下this 和 super 的区别

    pm -> property or method

    1.先说 this.pm 和 pm 一样 都是调用本类的方法 找不到本类的 再往上找

    2.this.pm 和 super.pm this.pm 先查看本类的没有往上找 super 直接看父类的 没有 再往上找

    3.this() 和 super( ) cv this() 先查看本类的没有往上找 super() 直接看父类的 没有 再往上找

3.多态(Polymorphisms)

1.方法重写/覆盖(override)

在继承条件下 子类对父类的方法进行内容的改变 返回值 方法名 修饰符都是一样的 形参列表相同

1.细节:/细节: 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类 (子类 String 父类 Object)

2.//细节: 子类方法不能缩小父类方法的访问权限 【演示】//public > protected > 默认>private

2.方法重载

方法在本类 方法名 必须一样 形参列表 类型要 不一样 返回 无要求 修饰符无要求

3.多态的正式介绍

1.什么是多态

方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。

我的理解:一个事物 类 有多种 表现形式

2.方法 的多态

 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));
//方法重写体现多态
B b = new B();
a.say();
b.say();
​
}

/方法重写体现多态
B b = new B();
a.say();
b.say();
}
}
class B { //父类
public void say() {
System.out.println("B say() 方法被调用...");
}
}
class A extends B {//子类
public int sum(int n1, int n2){//和下面 sum 构成重载
return n1 + n2;
}
public int sum(int n1, int n2, int n3){
return n1 + n2 + n3;
}
public void say() {
System.out.println("A say() 方法被调用...");
}
}

3.对象的多态

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

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

3.运行类型是可以变化的

4.编译类型 = 左边 运行类型 = 右边

Animal animal = new Cat()

问属性时 看他的编译类型

5.多态的细节

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

Animal animal = new Cat();

public class Test {
    public static void main(String[] args) {
//        Cat cat = new Cat("marry","pink");
//        cat.hello();//hello marry
​
        //向上转型
        Animal animal = new Cat("marry","pink");
        animal.hello();// 查找自己本类的hello marry 对父类的方法重写了
        animal.animal();//可以调用父类的方法
​
//
//        animal.hobby();//编译类型是Animal 直接编译Animal类型的属性和方法 运行类型是cat
​
       //向下转型
        Cat cat = (Cat) animal;// 这里的animal必须是指向当前目标类型的
        cat.hobby();
        cat.animal();//也可以调用父类 的方法
    }
}
​
public class Animal {
    private  String name;
​
    public Animal(String name) {
        this.name = name;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
    public void hello() {
        System.out.println("hello");
    }
    public void animal() {
        System.out.println("animal");
    }
​
}
public class Cat extends Animal{
    private String name;
    private String color;
​
    public Cat(String name, String color) {
        super(name);
        this.color = color;
    }
​
​
​
    public String getColor() {
        return color;
    }
​
    public void setColor(String color) {
        this.color = color;
    }
​
    @Override
    public void hello() {
        System.out.println("hello "+super.getName());
    }
    public void hobby() {
        System.out.println("I like fish");
    }
}

向下转型

Cat cat = (Cat) animal; // 这里把animal的运行类型 转化成了cat cat.catchMouse();//猫抓老鼠

注意点

1.属性没有重写之说!属性的值看编译类

2.只要编译过了才有运行类型

3.方法看 运行类型 向上转型的时候 调用 子类的特有方法是不可行的 因为编译没有过去

可以向下转型

4.instanceof 直接看运行类型是不是相等

4.java 的动态绑定机制(非常非常重要.)

1.当调用对象方法的时候 该方法会和该对象的内存地址 / 运行类型绑定

  1. 当调用对象属性的时 没有动态绑定 哪里申明 那里使用

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值