17.JAVA对象的进阶

JAVA对象的进阶

封装

  • 该露的露 该藏的藏
  • 高内聚(类的内部数据操作 自己完成 不允许外部操作) 低耦合(仅暴露少量的方法给外部使用)

Main

package JAVA.oop.demo4;
/*
1.提高程序的安装性 保护数据
2.隐藏代码的实现细节
3.同一接口 
4.提高了系统的可维护性
 */
public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();

        s1.setName("林宏程");

        System.out.println(s1.getName());

        s1.setAge(999);//不合法的年龄
        System.out.println(s1.getAge());

    }
}

Student

package JAVA.oop.demo4;
//private 属性私有
public class Student {


    //学习()
    //睡觉()

    //属性私有
    private String name;//姓名
    private int age;//年龄
    private int id;//学号
    private char sex;//性别

    //提供一些可以操作这些属性的方法
    //提供一些public的get set方法

    //get获得这个属性
    public String getName(){
        return this.name;
    }//alt+insert getter

    //set 给这属性设置值
    public void setName(String name){
        this.name=name;
    }//alt+insert setter

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age>120||age<0){
            this.age=3;
        }
       else {
            this.age = age;
        }
    }
}

重载(封装使用方法同样可以重载)

Arrays.fill() 一样的方法名 有不同的使用方法

package JAVA.oop.demo4;
import java.util.Arrays;

public class Application {
    public static void main(String[] args) {
        int[] a={1,2,3,4};

        Arrays.fill(a,0,1,2);//把数组里的0到1下标全换成2
        for (int i : a) {
            System.out.print(i+"\t");
        }

        Arrays.fill(a,0);//把数组里的数字全换成0
        for (int i : a) {
            System.out.print(i+"\t");
        }

    }
}

继承

  • 继承的本质是对另一个类的抽象
  • JAVA只有单继承 没有多继承 一个儿子只有一个爸爸 一个爸爸可以有多个儿子
  • 在使用继承后 子类里面有一个隐藏代码 super()

object

在JAVA中 所有的类都默认直接 间接继承object类

super

代码:

main

package JAVA.oop.demo5;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();

        student.test1("杨韬");
        System.out.println("--------------------------");

        student.test2();

    }
}
Person
package JAVA.oop.demo5;

//在JAVA中 所有的类都默认直接 间接继承object类
public class Person /*extends Object*/ {
    //public
    //protected
    //default
    //private
    private int money = 10_0000_0000;
    protected String name = "林宏程";

    public Person() {
        System.out.println("Person 无参执行了");
    }

    //私有的无法被继承
    private void say() {

        System.out.println("说了一句话");
    }

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

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}
Student
package JAVA.oop.demo5;

//学生 is 人
// 子类继承了父类 就会拥有父类的全部方法
//ctrl+H 查看这个类的类树的位置
public class Student extends Person {
    private String name = "林涛";

    public Student() {

        super();//这个是隐藏代码 调用了父类的无参构造 如果父类没有无参构造 那么必须加上父类的有参构造
        System.out.println("Student 无参执行了");
    }



    public void test1(String name) {
        System.out.println(name);//杨韬
        System.out.println(this.name);//林涛
        System.out.println(super.name);//林宏程
    }

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

    public void test2() {
        print();//Student
        this.print();//Student
        super.print(); //Person


    }

}
结果

在这里插入图片描述

super总结
  1. super调用父类的构造方法 必须在构造方法的第一个
  2. super必须只能出现在子类的方法 或者构造方法
  3. super和this 不能同时调用构造方法
  4. 子类无论任何构造器 他都必须调用super()不去写也会隐藏生成 如果没有无参构造(父类的) 那就必须用有参构造(父类)
public Student(String name) {
    super("bb");
    this.name = name;
}//像是这样 这样就可以不需要父类有无参构造了
this
代表的对象不同

this:调用本身这个对象

super 代表父类对象的应用

前提

this 没有继承也可以使用

super 只能在继承条件下才可以使用

构造方法的区别

this();本类的构造

super();父类的构造

方法的重写

代码
main
package JAVA.oop.demo5;

public class Application {
    public static void main(String[] args) {
        //静态和非静态方法有很大区别
        //静态方法 方法的调用 只和左边的类型有关
        //非静态方法 可以重写
        A a = new A();
        a.test();//A

        //父类的引用 指向了子类
        B b=new A();//子类重写了父类的方法
        b.test();//B
    }
}
A
package JAVA.oop.demo5;
//继承
public class A extends B {
    //Override 重写
    @Override//注解 有功能的注释
    public void test() {
        System.out.println("a=>test()");
    }
}
B
package JAVA.oop.demo5;

//重写都是方法的重写 和属性无关
public class B {

    public  void test() {
        System.out.println("b=>test()");

    }
}
结果

在这里插入图片描述

重写总结

需要有继承关系 子类重写父类方法

  1. 方法名必须相同
  2. 参数列表必须相同
  3. 修饰符 范围可以扩大 不能被缩小 public>protected>default>private
  4. 抛出的异常 范围可以被缩小 不能被扩大 classNOTFoundException–>Exception(大)

重写 子类的方法 和父类的方法必须一致 方法体不同

重写的原因
  1. 父类的功能 子类不一定需要 或者不一定满足
  2. alt+insert ---->override 快捷键

多态

个人理解多态:因为子类的里面包括父类 所以当以父类作为类型的时候 也可以new一个子类作为引用对象 方法用的是父类里的 但是需要用到子类的时候 也可以强转为子类去使用

相当于 学生 也是 人 所以 : 人 s1=new 学生();但是这个人 不是普通的人 而是引用了学生的人

但是不可以 学生 s1 =new人 因为不是所有人都是学生

个人理解多态的意义: 在不清楚这个person到底是student还是teacher的时候 我们先定义一个person的Person类 到我们见到这个人的时候 我们再去定义他是Student类还是Teacher类个人认为这节课的目的是让我们知道多态的存在 实际使用可能是直接先给个Person类 然后在程序运行到可以判断是学生还是老师的时候 再把person强转成student或者teacher

参考这里理解 https://segmentfault.com/q/1010000018449795

注意 子类如果重写了父类的方法 那么就会用到子类的

代码
main
package JAVA.oop.demo6;

public class Application {
    public static void main(String[] args) {
        //一个实际对象是确定的
        //new Student();
        //new Student();

        //可以指向引用类型就不确定了 父类的引用指向子类
        //Student 能调用的方法 都是自己的 和继承父类的
        Student s1 = new Student();
        //Person 父类型 可以指向子类 但是不能调用子类独有的方法
        Person s2 = new Student();
        Object s3 = new Student();

        s1.run();//子类重写了父类的方法 执行子类的方法
        s2.run();

        //对象能执行那些方法 主要对象左边的类型 和右边关系不大
        s1.eat();
        //Person 父类型 可以指向子类 但是不能调用子类独有的方法
        //s2.eat();
        ((Student)s2).eat();//必须把Person类型强转成Student类型才能调用Student独有的方法eat()


    }
}
Person
package JAVA.oop.demo6;

public class Person {
    public void run(){
        System.out.println("run");
    }
}
Student
package JAVA.oop.demo6;

public class Student extends Person {
    @Override
    public void run() {
        System.out.println("son");
    }
    public void eat(){
        System.out.println("eat");
    }
}
结果

在这里插入图片描述

多态的主要事项
  1. 多态是方法的多态 属性没有多态
  2. 父类和子类 有联系 类型转换异常 ClassCastException
  3. 存在条件:继承关系 方法需要重写 如果没有重写 优先执行子类的 父类引用指向子类 father f1 =new Son();
无法重写的方法
  1. static属于类 不属于实例
  2. final 常量
  3. private方法
instanceof
package JAVA.oop.demo6;

public class Application {
    public static void main(String[] args) {
        //object->String
        //Object->Person->Student
        //Object->Person-> Teacher
        Object object = new Student();
        //System.out.println(X instanceof Y);能不能编译通过

        System.out.println(object instanceof Student);//true
        System.out.println(object instanceof Person);//true
        System.out.println(object instanceof Object);//true
        System.out.println(object instanceof Teacher);//false
        System.out.println(object instanceof String);//false

        System.out.println("---------------------------");

        Person person=new Student();

        System.out.println(person instanceof Student);//true
        System.out.println(person instanceof Person);//true
        System.out.println(person instanceof Object);//true
        System.out.println(person instanceof Teacher);//false
        //System.out.println(person instanceof String);//编译报错

        System.out.println("---------------------------");
        Student student = new Student();
        System.out.println(student instanceof Student);//true
        System.out.println(student instanceof Person);//true
        System.out.println(student instanceof Object);//true
        //System.out.println(student instanceof Teacher);//编译报错
        //System.out.println(student instanceof String);//编译报错

    }
}
多态的总结
  1. 父类的引用 指向子类的对象
  2. 把子类转换为父类 向上转型 不用强制转换 可能丢失自己本来的一些方法
  3. 把父类转换为子类 向下转型 需要强制转换 可以获得子类独有的方法 同时也不会丢失自己的方法
  4. 方便方法的调用 减少重复的代码

static的详解

static在类里的执行顺序

package JAVA.oop.demo7;

public class Person {
    static {
        System.out.println("静态代码块");
        //静态代码块
    }//1只执行一次

    {
        System.out.println("匿名代码块");
        //代码块(匿名代码块)
    }//2 赋初始值


    public Person() {
        System.out.println("构造方法");
    }//3

    public static void main(String[] args) {
        Person person1 = new Person();
        System.out.println("--------------------------------------");
        Person person2 = new Person();


    }
}

static在类里的属性区别

package JAVA.oop.demo7;

public class Student {
    private static int age;//静态的变量
    private double score;//非静态的变量
    public void run(){
        go();
    }
    public static void go(){

    }

    public static void main(String[] args) {
        Student s1 = new Student();

        System.out.println(Student.age);
//      System.out.println(Student.score);
        System.out.println(s1.age);
        System.out.println(s1.score);

        new Student().run();

        Student.go();
        go();


    }
}

static的静态包

package JAVA.oop.demo7;
import static java.lang.Math.random;//静态导入包
import static java.lang.Math.PI;//π

public class Test {
    public static void main(String[] args) {
        System.out.println(Math.random());
    }
}

抽象类

特点

  1. 不能new这个抽象类 只能靠子类去实现他 约束
  2. 抽象类可以写普通的方法
  3. 抽象方法必须在抽象类中
  4. 抽象的抽象

代码

抽象类
package JAVA.oop.demo8;
//abstract 抽象类 类 extends 单继承  接口可以多继承
public abstract class Action {

    //约束
    //abstract 抽象方法 没有方法实现
    public abstract void doSomething();

    public Action() {
    }
}
重写抽象方法
package JAVA.oop.demo8;
//抽象类的所有方法 继承了它的子类 都必须实现他的方法 除非他的子类也是抽象类
public class A  extends Action{
    @Override
    public void doSomething() {

    }
}

抽象类的意义

抽象的意义:对代码的维护重用

1.因为抽象类不能实例化对象,所以必须要有子类来实现它之后才能使用。这样就可以把一些具有相同属性和方法的组件进行抽象,这样更有利于代码和程序的维护。

比如本科和研究生可以抽象成学生,他们有相同的属性和方法。这样当你对其中某个类进行修改时会受到父类的限制,这样就会提醒开发人员有些东西不能进行随意修改,这样可以对比较重要的东西进行统一的限制,也算是一种保护,对维护会有很大的帮助。
2.当又有一个具有相似的组件产生时,只需要实现该抽象类就可以获得该抽象类的那些属性和方法。
比如学校又新产生了专科生这类学生,那么专科生直接继承学生,然后对自己特有的属性和方法进行补充即可。这样对于代码的重用也是很好的体现。

所以,Java中抽象类对于代码的维护和重用有很好的帮助,也是Java面向对象的一个重要体现。

接口

普通类 只有具体的实现

抽象类 具体实现(通过子类)和规划(抽象方法)

接口 只有规范 专业的约束 约束和实现分离

接口的本质就是契约

作用

  1. 约束
  2. 定义一些方法 让不同的类实现 10----->1
  3. 方法都是 public abstract
  4. public static final
  5. 接口不能被实例化 接口没有构造结果
  6. 可以实现多个接口 implements
  7. 必须要重写接口中的方法

抽象类和接口区别

抽象类

就是比如我们熟悉的泰迪,哈巴,二哈,阿拉斯加,秋田犬等等大小形态有很大区别,我们怎么把他们抽象一下呢?那就是他们都有一些本质上相同的东西那就是他们都是狗,是狗就有耳朵,尾巴,四肢等等我们把这些给抽象出来,至于耳朵是啥样的,尾巴是长是短,颜色是啥,这就需要子类实现狗这个抽象方法了。

接口

接口就是一种特殊的abstract class,但是比abstract class更加抽象,

那么接口的作用是什么呢?

  1. Java单继承的原因所以需要曲线救国 作为继承关系的一个补充。
  2. 把程序模块进行固化的契约,降低偶合。把若干功能拆分出来,按照契约来进行实现和依赖。(依赖倒置原则)
  3. 定义接口有利于代码的规范。(接口分离原则)

abstract class 表示的是is a关系,interface表示的是like a关系。

内部类

就是在类的内部再定义一个类

这个现在可以不去了解

1.成员内部类

package JAVA.oop.demo10;

public class Application {
    public static void main(String[] args) {

        Outer outer = new Outer();

        Outer.Iner iner = outer.new Iner();

        iner.in();
        iner.getID();
        //通过这个外部类来实例化内部类
    }


}
package JAVA.oop.demo10;

public class Outer {
    private int id = 10;

    public void out() {
        System.out.println("这是外部类的方法");
    }
    //
      class Iner {
        public void in() {
            System.out.println("这是内部类的方法");
        }

        //获得外部类的私有属性
        public void getID() {
            System.out.println(id);
        }
    }

}
//一个java类可以有多个class文件 但是只有一个public class
class A{
    public static void main(String[] args) {
    }
}

2.静态内部类

package JAVA.oop.demo10;

public class Outer {
    private int id = 10;
    public void out() {
        System.out.println("这是外部类的方法");
    }
 
      static class Iner {
        public void in() {
            System.out.println("这是内部类的方法");
            System.out.println(id);//这里是取不到id的因为 static内部类比id先加载出来 最先加载的是静态变量 然后是代码块 然后才是构造方法
        }


    }

}

3.局部内部类

package JAVA.oop.demo10;

public class Outer {
 //局部内部类
    public void method(){
        class Inner{

        }
    }
}

4.匿名内部类

package JAVA.oop.demo10;

public class Test {
    public static void main(String[] args) {
        //没有名字 初始化类 不用将实例保存到变量中
        new Apple().eat();

        UserService userService = new UserService(){
            @Override
            public void hello() {

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

interface UserService{
    void hello();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值