2021.8.29~9.1面向对象

本文深入探讨了Java的面向对象特性,包括属性和方法的访问控制(public, private, final, static)、构造器的使用、this和super关键字的理解、构造器的调用规则以及对象的实例化过程。此外,还详细阐述了类的封装原则,强调了数据安全和隐藏实现细节的重要性。接着,介绍了继承的概念,展示了如何通过extends关键字创建子类,并讲解了super关键字的使用场景。文章进一步讨论了方法的重写(override),明确了重写的方法必须保持名称一致但实现不同,并分析了多态的概念及其在父类引用子类对象时的应用。最后,提到了抽象类和接口的定义以及内部类的使用,为读者提供了全面的Java面向对象编程知识概览。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面向对象

小笔记

  • 调用内部属性 对象.属性名

  • 调用方法 对象.方法名

  • 调用非静态方法 先new 再调用

  • 不可改动的,静态static是类的,final是固定的,private私有的

快捷键

  • 1.ALT+Insert(在功能区)
  • 可快速生成set/get/构造器
  • 2.Ctrl+H(在功能区)
  • 查看类关系

this关键字

  • 表示本类中的属性
  • 可供类内部调用

构造器

  • new的过程其实就是调用了类的构造器
  • new对象就是实例化
  • 无参构造是默认存在的
  • 在写重载方法时,必须在类里添加无参构造(不然会报错)!!!
public class Person {
    
    String name;
    int age;

    //添加构造器 无参构造
    //new的本质就是调用构造器方法
    public Person() {
        this.name = "name";
    }

    //一旦定义了无参构造,就必须(写)显示无参定义!!!!!
    public Person(String name) {
        // this.name代表类里String name;
        //name代表调用对象时传入的内容
        this.name = name;
    }
    public Person(int age) {
        this.age = age;
    }
    /*
    //new 实例化对象
        Person person = new Person();
        System.out.println(person.name);

     */

   }

//学生类
public class Student {
//定义属性
        //调用    对象名.name=...
    String name;//赋值操作 new 对象后 

    int age;

    //方法
    public void say(){
        //this表示类里面的变量
        System.out.println(this.name+"在说话");
    }
    public  int getAge(){
        return this.age;
    }


/*
 //new_对象,就是实例化
        Student student = new Student();
        student.name="小明";//这里就是定义属性
        student.age=18;

        student.say();
        System.out.println(student.getAge());
        //这里就是定义属性

 */
}


封装

  • *属性私有,get/set
  • 添加了private范围修饰符
  • 私有化后外部无法调用
  • 封装意义:
  • 提高安全性,保护数据
  • 隐藏代码实现细节
  • 统一接口
  • 系统可维护性
public class Student {
    //封装
    private String name;//外部不可调用
    private int age;
    public int 测试属性;//外部可直接调用

    //获取属性值
    public int getId() {
        return id;
    }
    //设置属性值

    public void setId(int id) {
        this.id = id;
    }

    private int id;
    private char sex;

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        //这里防止不合实际
        if (age > 120 || age < 0) {//避免非法内容
            this.age = 3;//如果非法输入,则返回3
        }
        this.age = age;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
   /*
     Student student = new Student();
     //private后 student.name="XingChenBeiTian";
     //不能被用户调用,只能通过set,get方法调用
        student.setName("XingChenBeiTian");
        System.out.println(student.getName());

    */
}

继承(extends)

  • 子类可获得父类方法,同时子类还可以写自己的方法

  • 父类

    //每个类都默认继承Object
    public class Person /*extends Object*/ {
        //定义一个课程进度
        //外部无法使用
        private double CourseProgress = 0.85;
    
    //set/get方便外部调用
        public double getCourseProGress() {
            return CourseProgress;
        }
    
        public void setCourseProGress(double courseProgress) {
            CourseProgress = courseProgress;
        }
    
        public void say(){
            System.out.println("星辰北天,java学习小白");
        }
    }
    
    
  • 子类

    public class Student extends Person{
    
    //新的方法,和父类不同
        //子类可以用父类public方法和变量属性
    public void tell(){
        System.out.println("新方法");
    }
    }
    

super关键字

  • 注意点

    1. super调用父类构造方法,必须在构造方法中的第一个
    2. super必须只能出现在子类的方法或者方法!!!!
    3. super和this不能同时调用构造方法
  • VS this:

  • 代表对象不同

    1. this 本身调用对象
    2. super 父类对象应用
  • 前提

    1. this 没有继承也可用
    2. super 只能在继承类中用
  • 构造方法

    1. this(); 本类的构造
    2. super; 福利地构造
//这是父类
public class Father {

    protected String name="XingChenBeiTian";

    public Father() {
        System.out.println("父类构造");
    }
}

//===========================================
//这是子类
public class Son extends  Father{
    protected String name = "星辰北天";

    //添加构造器


    public Son() {
        //写super();//必须放第一位
        super();//这个时默认的可以不写
       // this();//两个不能同时写
        System.out.println("子类构造");
    }


    //引用父类
    public void say(String name) {
        System.out.println(name);//方法传入
        System.out.println(this.name);//本类调用
        System.out.println(super.name);//父类调用
    }
}


/*
    //函数入口
    public static void main(String[] args) {
        Son son = new Son();
        son.say("java小白");
    }
    
    */


重写(override)

  • 重写只是方法的重写与属性无关

  • 重写子类(((方法名必须与父类相同))),方法体不同!!!

  • 修饰符范围可以扩大但不能缩小

    public>protected>Default>proviate

  • 否则会抛出异常,ClassNotFoundException–》Exception(大)

  • 使用前提(为什么重写)

  • 父类的方法满足不了使用,子类一定1需要,父类不一定需要

//父类
//重写只是方法的重写与属性无关
public class B {
    public void say(){
        System.out.println("B父类:test");

    }

    public static void tell(){
        System.out.println("静态B");
    }
}
//=============================================================

//子类继承
public class A  extends B{
    @Override
    public void say() {
        System.out.println("子类:Atest");
    }
    public static void tell(){
        System.out.println("静态A");
    }
}
//===================================================================
 //函数入口
    public static void main(String[] args) {
/*
静态的重写方法属于重载,可以理解为类的方法,静态不能重写
非静态的方法重写,可以理解为对象的方法


下面的,左边是属于类的,引用的方法也都是类的方法
右边是new出来的对象
        B b = new A();

 */
     A a=new A();//子类A
     //父类的引用指向了子类,多态
     B b = new A();//父类B
     a.tell();//静态调用
     a.say();
     b.tell();//静态方法
    }

个人

  • 静态的重写方法可以理解为重载,是类的方法,静态不能(不算,因为调用的都是自己类的方法)重写

  • 非静态的方法重写,可以理解为对象的方法

    下面的,左边(B)是属于类的,引用的方法也都是类的方法
    右边是new出来的对象
    B b = new A();

  • ALT+Insert

  • 非静态的是重写

  • 静态的不是

多态(instanceof判断是否有关系)

  • 方法的多态

  • 有继承关系

  • 父类可以指向子类,但不能调用子类的方法

  • Person person=new Son();
         ((Son)person).tell();//tell子类方法,父类Person调用只能强转
    
  • 代码还是上面的改动

  • 实例

//父类
public class B {
public void say(){
System.out.println(“B父类:test”);

  }

}
//=============================================================

//子类继承
public class A extends B{
@Override
//重写
public void say() {
System.out.println(“子类:Atest”);
}
//多态的
public static void tell(){
System.out.println(“静态A”);
}
}
//===================================================================
//函数入口
public static void main(String[] args) {
A a=new A();//子类A

   //父类的引用指向了子类,多态
   B b = new A();//父类B
   a.say();

   b.tell();//静态方法
   ((A)b).tell();//强转调用子类方法
  System.out.println(A instanceof B);//判断是否有关系
   System.out.println(Object instanceof B);//判断是否有关系   
      //同层不可比较
      
  }

> 个人

- 调用的类方法只与**(=)**前有关,与后面的关系不大!!!!!!!

- 必须**(关系)**类,方法需要重写,父类调用子类方法要强转(父类指向子类)

```java
   ((子类)父类).子类方法();//强转调用子类方法
  • 类转换异常ClassCastException

        //高         低
        父类 a = new 子类();
        ((子类) a).子类方法();
        //低     高
        子类 obj =new 子类();
        父类 b = obj;
        b.子类方法();

        /*父类引用指向子类对象
        *高----低 向下转换,强制转换,会丢方法
        *低----高 向上转换,直接转换
        * 作用:简化代码,提高利用率
        * */

代码块,static和final

  • 就直接代码演示了
public final class 父类 {
    //如果类被final修饰后子类就不能继承了(断子绝孙了--_--)

        {//2
            System.out.println("匿名代码块");
        }
        static {//1,只能执行一次,可用来赋初始值
            System.out.println("静态代码块");
        }

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

    public static void main(String[] args) {

        父类 x = new 父类();
        System.out.println("=========");
        父类 x2 =new 父类();

    }
}

个人

  • 代码块在构造器之前执行(可匿名)
  • static静态代码块每个类只能加载一次(可用来赋初始值)
  • final(常量)修饰的类不能被继承

静态导入包(节省使用一次的代码)

//静态导入包
import static java.lang.Math.random;//随机数
import static java.lang.Math.PI;//圆周率

public class Test {
    public static void main(String[] args) {
        //可以不写成Math.random的形式
        System.out.println(random());
        System.out.println(PI);
    }

个人

  • 直接看代码就OK

抽象(abstract)

  • 父类
//abstract抽象类,extends单继承 子类继承需要实现方法,除非子类也是abstract类  (接口可多继承)
public abstract class 抽象 {

    //java有约束,需要别人来实现
    //abstract抽象只有方法,没有方法的实现
    public abstract void 抽象方法名();
    //不能new
    //抽象类中可以写正常方法
    //抽象方法必须再抽象类里


  • 子类
public class 子类 extends 抽象 {

    @Override
    public void 抽象方法名() {
//这里实现抽象方法
    }

个人

  • 直接看代码就OK

接口的定义与实现

  • 接口定义
  • 接口1
//关键字interface,接口类都需要有实现类
public interface 接口1 {

    //常量~public final
    int 年龄 = 18;


    //接口中定义的方法其实都是public abstract
    public abstract void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}

  • 接口2
public interface 接口2 {
    void say(String name);
}
  • 实现类
//需要导包
//实现接口方法,关键字implements   接口可多继承(接口1,接口2)
public class 实现类 implements 接口1, 接口2 {
    //接口1方法
    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }
//接口2方法
    @Override
    public void say(String name) {

    }
}

个人

  • 没有构造器,不能new,实现类需要重写(所有接口方法)
  • java常用的开发模式
  • 别人写接口,我们实现对应方法
  • 很关键,也很抽象

内部类

  • 成员内部类

//外部类
public class 成员内部类 {
    private int id = 10;

    public 成员内部类() {
        System.out.println("外部类");
    }
    //成员内部类
    class Inner {
        public void in() {
            System.out.println("成员内部类");
        }

//可以调用外部变量
        public int getId() {
            return id;
        }
    }
}
  • 调用

        public static void main(String[] args) {
            成员内部类 outer =new 成员内部类();
            成员内部类.Inner inner = outer.new Inner();
            inner.in();
            System.out.println(inner.getId());
        }
    
  • 局部内部类

public class 局部内部类 {
    public void in() {
      class 局部内部{
//这里写方法
        }
    }
}

个人

  • 接口可以new
  • 但要实现接口所有的方法
//new接口
        接口1 user1=new 接口1(){
            @Override
            public void add(String name) {
                
            }

            @Override
            public void delete(String name) {

            }

            @Override
            public void update(String name) {

            }

            @Override
            public void query(String name) {

            }
        };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值