阅读 59

java学习

Java 封装

封装的介绍

封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。

封装的好处

1.可以隐藏实现的细节

2.可以对数据进行验证,保证其安全合理性

构造器和Set xx结合

java继承

1.关键字 extends

可以理解为代码的复用性,当多个类拥有相同的属性和方法时,我们可以从抽象出来一个父类,在这个父类定义相同的方法或属性,所有的子类不必重复去定义这些属性和方法,只需要用extends继承

注意

子类继承了父类的所有属性和方法,但是私有属性和方法不能在子类直接反问,要提供公共的方法来反问

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

//父类
public class Student {
      public Student() {
        System.out.println("父类构造器----");
    }

}
//子类
public class Student2 extends Student{
    public Student2(){
       //为什么会调用父类的构造器
      //super(); 这里默认去调用父类的无参构造器,写不写都有
        System.out.println("子类0000");
    }

}
//测试
public class Text {
    public static void main(String[] args) {
        Student2 s=new Student2();
    }
}
结果  创建的是子类,先调用的是父类的构造器在调用子类构造器
  //父类构造器---- 
  //子类0000
复制代码

但创建子类对象时,不管使用子类的有参还是无参构造器,默认都是先调用父类的无参构造器,参xv'cvb

这里我们把父类改成一个有参构造器

public class Student2 extends Student{
    public Student2(String name){
        System.out.println("子类0000");
    }
}

public class Student2 extends Student{
    public Student2(){
      //父类没有提供无参构造器,这里就super去指定具体的父类构造器
        super("miss");
        System.out.println("子类0000");
    }

}
复制代码

注意super,this关键字在使用时,必须放到构造器的第一行(只能在构造器中使用),this和sper不能共存在一个构造器

java的所有类都是Object类的子类

父类构造器的调用不限于直接父类,就往上追索到object顶级父类

java是单继承,就是一个子类只能有一个直接父类,可以有多个间接父类,例如 A->B->C

java继承本质讲解

例子

public class Text2 {
    public static void main(String[] args) {
     Sun s=new Sun();
    }
}
class GrandPa{
    String name="大头爷爷";
    String hobby="旅游";
}
class Frather extends GrandPa{
    String name="大头爸爸";
    int age=39;
}
class Sun extends Frather{
    String name="小头儿子";

}
复制代码

基本数据类型存在堆中

引用数据类型的值实际存在方法区中常量值中

大概加载步骤是,从大到小

如果去访问它的属性name和age,这可以说是就近原则,就是先从子类找一直到object类,通俗就是你没有,找你爸爸要->你爷爷->你老祖,如果没有就真没有

public class Text2 {
    public static void main(String[] args) {
     Sun s=new Sun();
        System.out.println(s.name);
        System.out.println(s.age);
    }
}
//结果
小头儿子
39

复制代码

方法的重写

类中重写父类方法建立在继承的基础之上的

1.子类的参数,方法名称要和父类一样

2.子类的返回类型要和父类的返回类型一样,或者是父类返回类型的子类

父类方法
  public Object info(){
  return true;
}
子类方法
子类和父类的返回类型一样
  public Object info(){//可以
  重写内容
}
或者是父类返回类型的子类
  public String info(){
  重写内容
}//可以
复制代码

3.子类方法不能缩小父类的访问权限

例如父类的权限
String info(){}
子类
private String info(){}//错误

public  String info(){}//正确
复制代码

重载和重写比较

名称发生范围参数列表(形参)返回类型方法名修饰符
重载一般在本类类型,形参个数不同,顺序必须有一个不同没有要求必须一样一样
重写父子类必须一样一致,或是其子类必须一样一样或更大,不能比父类小

面向对象--多态

多态可以提高代码复用性和更利于维护

多态的使用时建立在封装和继承的基础上

多态核心

1.一个对象的编译类型可以和运行类型不一致(编译看左边,运行看右边)

//例如 这是一个父类的引用指向狗这个子类的对象
Animal  animal=new Dog(); 这编译是Animal运行类型是Dog
复制代码

2.编译类型在定义对象时就确定了,不可以改变

3.运行类型可以改变的

// 这是一个父类的引用指向猫这个子类的对象
Animal animal=new Cat();
复制代码
package com.TaoGe.java;

public class Animal {
    public void to(){
        System.out.println("动物咆哮");
    }
}
class Dog extends Animal{

 public void to(){
     System.out.println("狗子旺旺叫");
 }
}
class cat extends Animal{
    @Override
    public void to() {
        System.out.println("猫喵喵叫");
    }
}
class Text{
    public static void main(String[] args) {
        Animal a=new Dog();
      //执行到这运行类型是Dog
         a.to();// 狗子旺旺叫
      
        Animal a2=new cat();
      //执行到这运行类型是cat
        a2.to();//猫喵喵叫
    }
}
复制代码

多态向上转型

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

可以调用父类所有成员(注意访问权限)

不能调用子类特有成员(private修饰)

最终运行效果也是先从子类开始找,如果没有,则到父类

package com.TaoGe.java;

public class Person {
    public void eat(){
        System.out.println("人吃饭");
    }
    public  void work(){
        System.out.println("人散步");
    }

}
class  student extends Person{
    @Override
    public void eat() {
        System.out.println("学生吃饭");
    }
}
class Test3{
    public static void main(String[] args) {
        student s=new student();
         s.eat();//学生吃饭
      
      //这里子类没有work这个方法,父类有并且可以调用,则运行父类的
         s.work();//人散步
    }
}
复制代码

多态向下转型

基本语法

  子类类型 引用名=(子类类型)父类引用
复制代码

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

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

多态的细节

1.属性没有重写之说,运行和编译看左边,和方法不同

package com.TaoGe.java;

class A{
    int base=3;
}

class B extends  A{
    int base=5;
}

public class Text4 {
    public static void main(String[] args) {
        A a=new A();
        System.out.println(a.base);//3
    }

}


复制代码

InstanceOf

结论:InstanceOf用来判断对象的运行时类型是某个类型,或为它的子类型

package com.TaoGe.java;

class A{}

class B extends  A{}

public class Text4 {
    public static void main(String[] args) {
        B b=new B();
        System.out.println(b instanceof B);//true
        System.out.println(b instanceof A);//true

        A a=new B();
        System.out.println(a instanceof A);//true
        System.out.println(a instanceof B );//true
    }

}

复制代码

java的动态绑定机制

1.但调用对象方法时,该方法就会和该对象的内存地址/运行类型判定

2.当调用对象属性时,没有动态判定机制,哪里调用哪里使用

简单实例

package com.TaoGe.java;

public class Text4 {
    public static void main(String[] args) {
    A a=new B();//向上转型
        System.out.println(a.sum());//40    ?但子类没有sum方法时结果   30
        System.out.println(a.sum1());//30    ? 但子类没有sum1方法时结果   20
    }

}
class A{
 public  int i=10;

 public int sum(){
     return getI()+10;
 }

 public int sum1(){
     return i+10;
 }

 public int getI(){
     return i;
 }
}

class B extends A{
    public int i=20;

    @Override
//    public int sum() {
//        return i+20;
//    }
    public int getI(){
        return i;
    }


//    public int sum1() {
//        return i+10;
//    }
}
复制代码

多态数组

数组的定义类型为父类类型,实际保存的是子类类型

package com.TaoGe;

public class Person {
    private String name;
    private  int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    public String say() {
         return name + "\t" + age;
    }
}

class Student  extends Person{
     private double score;

    public Student(String name, int age,double score) {
        super(name, age);
        this.score=score;
    }

    public double getScore() {
        return score;
    }

    @Override
    public String say() {
        return super.say()+"score="+score;
    }

    public void setScore(double score) {
        this.score = score;
    }
    public void study(){
        System.out.println("学生"+getName()+"正在学习");
    }
}
class  Teacher extends Person{
    private double salary;

    public Teacher(String name, int age,double salary) {
        super(name, age);
        this.salary=salary;
    }

    @Override
    public String say() {
        return super.say()+"salary="+salary;
    }
    public void teach(){
        System.out.println("老师"+getName()+"正在上课");
    }
}
class Test{
    public static void main(String[] args) {
        Person[] p=new Person[5];
        p[0]=new Student("awea",23,45.5);
        p[1]=new Student("aeae",323,12.3);
        p[2]=new Student("ccc",24,232.4);
        p[3]=new Person("ddd",44);
        p[4]=new Teacher("aea",34,60000);

        for (int i = 0; i <p.length ; i++) {
            //编译类型是person,运行类型根据jvm来决定
            System.out.println(p[i].say());//动态绑定

            //这里调用子类特有的方法,根据类型判断和向下转型
             if (p[i] instanceof Student){
                 ((Student)p[i]).study();
             }else if (p[i] instanceof Teacher){
                 ((Teacher)p[i]).teach();
             }else if (p[i] instanceof Person){

             } else {
                 System.out.println("类型有误");
             }
        }
    }

}
复制代码

多态参数

方法定义的形参为父类类型,实参允许为子类类型

实战!

package com.TaoGe;

public class Employee {
    private String name; //名字
    private double salary;//月工资

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
    //计算年工资
    public double getAnnual(){
        return salary*12;
    }
}

class Worker extends Employee{

    public Worker(String name, double salary) {
        super(name, salary);
    }
    public void towork(){
        System.out.println("普通员工"+getName()+"打工人,人上人");
    }

    @Override
    public double getAnnual() {
        return super.getAnnual();
    }
}
class manager extends Employee{
 private double bonus;//奖金

    public manager(String name, double salary,double bonus) {
        super(name, salary);
        this.bonus=bonus;
    }
    public void maage(){
        System.out.println("经理"+getName()+"管理公司");
    }

    @Override
    public double getAnnual() {
        return super.getAnnual()+bonus;
    }
}
class Text{
    public static void main(String[] args) {
        //创建当前类的实例
        Text t=new Text();
        //经理
     Employee e=new manager("aaa",3000,2000);
      System.out.println(t.showEmAnnus(e));
        t.testWork(e);
        //普通员工
        Employee c=new Worker("bbb",2000);
        System.out.println(t.showEmAnnus(c));
        t.testWork(c);
    }

    public double showEmAnnus(Employee e){
        return e.getAnnual();
    }
    public void testWork(Employee c){
        if (c instanceof Worker){
            ((Worker)c).towork();
        }else  if (c instanceof manager){
            ((manager)c).maage();
        }else if (c instanceof  Employee){

        }else {
            System.out.println("啥也不是");
        }
    }
}
复制代码
文章分类
后端
文章标签