Java面向对象

9 篇文章 0 订阅
本文详细介绍了Java的面向对象编程,包括类与对象的关系、对象创建与内存分析、封装、继承、多态等核心概念。通过实例解析了构造器、抽象类、接口以及内部类的使用,强调了面向对象的三大特性——封装、继承和多态在实际编程中的应用。
摘要由CSDN通过智能技术生成

Java面向对象

Java核心思想就是OOP

目录

Java面向对象

初识面向对象

1、面向过程&面向对象

2、什么事面向对象

方法回顾和加深

对象的创建分析

1、类与对象的关系

2、创建初始化对象

3、构造器

4、创建对象内存分析

5、小结

面向对象三大特征

1、封装

2、继承

3、多态

4、static

抽象类和接口

1、抽象类

2、接口

内部类及OOP实战

1、内部类


初识面向对象

1、面向过程&面向对象

  • 面向过程思想

    • 步骤清晰简单,第一步做什么,第二步做什么......

    • 面对过程适合做一些较为简单的问题

  • 面向对象思想

    • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索

    • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!

  • 对于描述复杂的事物,为了从宏观上把握,从整体上合理分析我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理

2、什么事面向对象

  • 面向对象编程(Object-Orented Programing,OOP)

  • 面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据。

  • 抽象

  • 三大特性:

    • 封装

      ​​

      继承

      ​​

      多态

  • 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象

  • 从代码运行角度考虑是先有类后有对象。类是对象的模版。

方法回顾和加深

  • 方法的定义

    • 修饰符

    • 返回类型

    • break和return区别

    • 方法名:见名知意

    • 参数列表:(参数类型,参数名)...(可变参数)

    • 异常抛出

  • 方法的调用:递归

    • 静态方法

    • 非静态方法

    • 形参和实参

    • 值传递和引用传递

    • this关键字

//学生类
public class Student {
​
   //方法
   public void say(){
       System.out.println("学生说话了");
  }
}
public class Demo02 {
   public static void main(String[] args) {
       //实例化
       //对象类型 对象名=对象值
       Student stu= new Student();
       stu.say();
  }
​
   //静态方法 static
​
   //非静态方法
}
​
/*
输出结果:
学生说话了
*/

对象的创建分析

1、类与对象的关系

  • 类是一种抽象的数据类型,他是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物

    • 动物、植物、手机、电脑.......

    • Person类、Pet类、Car类等,这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为。

  • 对象是抽象概念的具体事例

    • 张三就是人的一个具体事例,张三家里的旺财就是狗的一个具体实例。

    • 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念。

2、创建初始化对象

  • 使用new关键字创建对象

  • 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。

  • 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器又一下俩个特点:

    • 1、必须和类的名字相同

    • 2、必须没有返回类型,也不能写void

  • 构造器必须要掌握

//学生类
public class Student {
​
   String name;
   int age;
   //方法
​
   public void study(){
       System.out.println((this.name+"在学习"));
  }
}
//一个项目应该只能存在一个main方法
public class Demo06 {
   public static void main(String[] args) {
       //类是抽象的,需要实例化
       Student xiaoming=new Student();
       Student xiaohong=new Student();
​
       xiaoming.name="小明";
       xiaoming.age=3;
       xiaohong.name="小红";
       xiaohong.age=4;
​
       System.out.println(xiaoming.name);
       System.out.println(xiaoming.age);
       System.out.println(xiaohong.name);
       System.out.println(xiaohong.age);
  }
}
​
/*
输出结果:
     小明
     3
     小红
     4
*/

3、构造器

public class Demo07 {
   public static void main(String[] args) {
       //实例化对象
       Person per = new Person();
       System.out.println(per.name);
  }
}
​
/*
  构造器:
   1、和类名相同
   2、没有返回值
  作用:
   1、new 本质在调用构造方法
   2、初始化对象的值
   3、定义了有参构造之后,如果想使用无参构造,显示的定义一个无参构造
*/
public class Person {
   //一个类即使什么都不写,他也会存在一个方法
   //显示的定义构造器
​
   String name;
   int age;
   //实例化初始值
   //1、使用new关键字,本质是在调用构造器
   public Person(){
  }
​
   //实例化初始值
   //1、使用new关键字,本质是在调用构造器
​
   //快速创建有参构造函数
   //command+N(Mac)
   //alt+insert(Windows)
   public Person(String name) {
       this.name = name;
  }
​
   public Person(int age) {
       this.age = age;
  }
}
​
/*
输出结果:
null
*/

4、创建对象内存分析

public class Pet {
   public String name;
   public int age;
​
   //无参构造
   public void shout(){
       System.out.println("叫了一身");
  }
}
public class Demo08 {
   public static void main(String[] args) {
       Pet dog= new Pet();
       dog.name="旺财";
       dog.age=3;
       dog.shout();
​
       System.out.println(dog.age);
       System.out.println(dog.name);
  }
}
​
/*
输出结果:
     叫了一身
     3
     旺财
*/

 

5、小结

1⃣️类与对象

类是一个模版:抽象,对象是一个具体实例:具体

2⃣️方法

定义、调用

方法详解

3⃣️对应的引用

引用类型:基本类型(八个)

对象是通过引用来操作的:栈——>堆

4⃣️属性:字段Field 成员变量

默认初始化: 数字:0 0.0

char:u0000

boolean:false

引用:null

修饰符 属性类型 属性名 =属性值!

5⃣️对象的创建和使用

a.必须使用new 关键字创造对象,构造器 Person tomyoung=new Person()

b.对象的属性 tomyoung.name

c.对象的方法 tomyoung.sleep()

6⃣️类

静态的属性

动态的方法

面向对象三大特征

1、封装

  • 该露的露,该藏的藏

    • 我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅露出少量的方法给外部使用。

  • 封装(数据的隐藏)

    • 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。

  • 属性私有,get/set

public class Student {
​
   //属性私有
   private String name; //名字
   private int id;//学号
   private char sex;//性别
   private int age;//年龄
​
   //提供一些可以操作属性的方法!
   //提供一些public的get、set方法
​
   //get获得这个数据
   public String getName(){
       return this.name;
  }
​
   //set给这个数据设置值
   public void setName(String name){
       this.name=name;
  }
​
   public int getId() {
       return id;
  }
​
   public void setId(int id) {
       this.id = id;
  }
​
   public int getAge() {
       return age;
  }
​
   public void setAge(int age) {
       if(age>120||age<0){
           this.age=3;
      }else{
           this.age=age;
      }
  }
}
import OOP.Demo11.Student;
​
/*
1、提高程序安全性,保护数据
2、隐藏代码的实现细节
3、统一接口
4、系统可维护性
*/
public class Demo10 {
   public static void main(String[] args) {
       Student s1=new Student();
       s1.setName("tomyoung");
       System.out.println(s1.getName());
       s1.setId(19100115);
       System.out.println(s1.getId());
       s1.setAge(999);
       System.out.println(s1.getAge());
  }
}
​
/*
输出结果:
     tomyoung
     19100115
     3
*/

2、继承

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模

  • extands的意思是“扩展”。子类是父类的扩展。

  • JAVA中类只有单继承,没有多继承!

  • 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。

  • 积尘关系的俩个类,一个位子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extands来表示。

  • 子类和父类之间,从意义上讲应该具有“is a”的关系。

    //父类
    public class Person {
       private int money=100000;
       public void say(){
           System.out.println("说了一句话");
      }
    ​
       public int getMoney() {
           return money;
      }
    ​
       public void setMoney(int money) {
           this.money = money;
      }
    }
    //子类
    public class Student extends Person {
    }
    import OOP.Demo12.Student;
    ​
    public class Demo13 {
       public static void main(String[] args) {
           Student s1=new Student();
           s1.say();
      }
    }
    ​
    /*
    输出结果:
         说了一句话
    */

1⃣️object类

在Java中所有的类,都默认直接或间接继承object类

2⃣️super

注意点:

  1. super调用父类构造方法,必须在构造方法的第一个

  2. super必须只能出现在子类方法或者构造方法中!

  3. super和this不能同时调用构造方法!

this:

  1. this:本身调用者这个对象

  2. super:代表父类对象的应用

前提:

  1. this:没有继承也可以调用

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

构造方法的区别:

  1. this():本类的构造

  2. super():父类的构造

public class Person {
   public Person(){
       System.out.println("p无参构造执行");
  }
   protected String name="tomyoung";
   public void print(){
       System.out.println("Person");
  }
   //私有东西无法被继承
}
public class Students extends Person {
   //隐藏代码,调用了父类无参构造
   public Students(){
       System.out.println("s无参构造执行");
  }
   private String name="tomyoung1";
   public void print(){
       System.out.println("Student");
  }
   public void test(String name){
       System.out.println(name);
       System.out.println(this.name);
       System.out.println(super.name);
  }
   public void test1(){
       print();
       this.print();
       super.print();
  }
}
import OOP.Demo12.Students;
​
public class Demo13 {
   public static void main(String[] args) {
       Students s1=new Students();
       //s1.test("tomyoung2");
       s1.test1();
  }
}
​
/*
输出结果:
     p无参构造执行
     s无参构造执行
     Student
     Student
     Person
*/

3⃣️方法重写

//父类
public class B {
   protected void test(){
       System.out.println("B=>test");
  }
}
//子类
public class A extends B{
   @Override//注解;有功能的的注释
   public void test() {
       System.out.println("A=>test");
  }
}
public class App {
​
   //静态的方法和非静态方法区别很大
   //静态方法:只和方法调用的左边定义的数据类型有关
​
   //非静态:重写
   public static void main(String[] args) {
       //方法的调用只和定义的数据类型有关
       A a=new A();
       a.test();
​
       //父类的引用指向子类
       B b=new A();
       b.test();
​
  }
}
​
/*
输出结果:
     A=>test
     A=>test
*/

重写:需要有继承关系,子类继承父类的方法!

  1. 方法名必须相同

  2. 参数列表必须相同

  3. 修饰符:范围可以扩大但不能缩小

  4. 抛出的异常可以被缩小但不能被扩大

重写,子类的方法名必须一致,方法体不同

为什么需要重写:

父类的功能,子类不一定需要,或者不一定满足!

3、多态

多态基础

  • 动态编译:类型:可扩展性

  • 即同一方法可以根据发送对象的不同而采用多种不同的行为方式。

  • 一个对象的实际类型是确定的,但可以指向对象的引用类型有很多

  • 多态存在的条件

    • 有继承关系

    • 子类重写父类方法

    • 父类引用指向子类

  • 注意⚠️:多态是方法的多态,属性没有多态性。

//父类
public class A {
   public void run(){
       System.out.println("run");
  }
}
//子类
public class B extends A {
   public void run(){
       System.out.println("son");
  }
​
   public void eat(){
       System.out.println("吃 ");
  }
}
public class APP {
   public static void main(String[] args) {
       //一个类型的实际类型是确定的
       //new A()
       //new B()
​
       //可以指向的引用类型就不确定了:父类的引用指向子类
       B b = new B();//可以调用自己的方法和继承的方法
       A a = new B();//只能调用A的方法,不能调用子类独有的方法
​
       b.run();
       a.run();//子类重写父类方法,执行子类
​
       //对象能执行那些方法,主要看对象左边的类型,和右边关系不大
       a.eat();//报错
       b.eat();
  }
}

⚠️注意事项

  1. 多态是方法的多态,属性没有多态

  2. 父类和子类,有联系 类型转换异常!ClassCastException!

  3. 存在条件:继承关系,方法需要重写,父类引用指向子类!Father f1=new Son();

    哪些方法不能重写:

    1. static方法,属于类,他不属于实例

    2. final常量

    3. private方法;

instanceof

public class App {
   public static void main(String[] args) {
       Object obj=new Stu();
       System.out.println(obj instanceof Stu);
       System.out.println(obj instanceof Per);
       System.out.println(obj instanceof Object);
       System.out.println(obj instanceof Tea);
       System.out.println(obj instanceof String);
​
       Per per=new Stu();
       System.out.println(per instanceof Stu);
       System.out.println(per instanceof Per);
       System.out.println(per instanceof Object);
       System.out.println(per instanceof Tea);
       //System.out.println(per instanceof String);//编译报错
​
       Stu stu=new Stu();
       System.out.println(stu instanceof Stu);
       System.out.println(stu instanceof Per);
       System.out.println(stu instanceof Object);
       //System.out.println(stu instanceof Tea);//编译报错
       //System.out.println(stu instanceof String);//编译报错
  }
}
​
/*
输出结果:
     true
     true
     true
     false
     false
     true
     true
     true
     false
     true
     true
     true
*/

类型转换

public class App {
   public static void main(String[] args) {
       //类型之间的转化:父   子
       //高到低
​
       Per obj=new Stu();//Per父类、Stu子类
       Stu stu=new Stu();
       //将这个对象转换成Stu类型,就可以使用Stu的方法,高转低,强制转换
      ((Stu)obj).go();
​
       //子类转父类可能丢失一些方法
       Per per=stu;
  }

总结

  1. 父类的引用指向子类的对象

  2. 把子类转换为父类,向上转型

  3. 把父类转换为子类,向下转型;强制转换

  4. 方便方法的调用,减少重复的代码!

抽象:封装、继承、多态

4、static

public class Student {
   private static int age;//静态变量 多线程会用到
   private double score;//非静态变量
​
   public static void main(String[] args) {
       Student stu= new Student();
       System.out.println(stu.score);
       System.out.println(stu.age);
       System.out.println(Student.age);
       //System.out.println(Student.score);//报错,非静态变量不能使用类名加属性名调用
​
       Student.go();
       go();
       //Student.run();//报错
       //run();//报错
  }
   public void run(){
       go();
  }
   public static void go(){}
}
public class Person {
  {
       //代码块(匿名代码块)一般用于赋初始值
       System.out.println("匿名代码块");
  }
​
   static {
       //静态代码块,只输出一次
       System.out.println("静态代码块");
  }
​
   public Person(){
       System.out.println("构造方法");
  }
​
   public static void main(String[] args) {
       Person per=new Person();
       Person per1=new Person();
  }
}
​
/*
输出结果:
     静态代码块
     匿名代码块
     构造方法
     匿名代码块
     构造方法
*/
//静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
​
public class Test {
   public static void main(String[] args) {
       System.out.println(random());
       System.out.println(PI);
  }
}
​
/*
输出结果:
     0.4836455424563587
     3.141592653589793
*/

抽象类和接口

1、抽象类

  • abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果就是类,就是抽象类

  • 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。

  • 抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。

  • 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。

  • 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。

//抽象类(接口可以多继承)
public abstract class Action {
​
   //约束,有人帮我们实现
   //抽象方法
   public abstract void doSomething();
​
   //1、不能new抽象类,只能靠子类实现他:约束!
   //2、抽象类中可以写普通方法
   //3、抽象方法必须在抽象类中
   //抽象的抽象:约束
   public void say(){}
}
//抽象类的所有方法,继承他的子类,必须实现他的方法,除非他的子类也是抽象类
public class A extends Action {
   @Override
   public void doSomething() {
​
  }
}

2、接口

  • 普通类:只有具体实现

  • 抽象类:具体实现和规范(抽象方法)都有!

  • 接口:只有规范!自己无法写方法,约束和实现分离:面向接口编程~

  • 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是...则必须能....”的思想,如果你是天使,则必须能飞。如果你是汽车,则必须能跑。

  • 接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。

  • OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(C++、Java、C#),就是因为设计模式所研究的,实际上就是如何合理的去抽象。

    声明类的关键字是class,声明接口的关键字是interface

//接口都需要有实现类
public interface User {
   //接口中所有定义其实都是抽象的,public abstract
     void add(String name);
     void delete(String name);
     void update(String name);
     void query(String name);
}
public interface Time {
   void timer();
}
//一个类可以实现接口。implement接口,多继承!
//实现接口的类,就必须重写接口的方法
​
//利用接口实现多继承
public class UserImp implements User,Time {
   @Override
   public void query(String name) {
​
  }
​
   @Override
   public void update(String name) {
​
  }
​
   @Override
   public void delete(String name) {
​
  }
​
   @Override
   public void add(String name) {
​
  }
​
   @Override
   public void timer() {
​
  }
}

作用:

  1. 约束

  2. 定义一些方法,让不同的人实现

  3. 方法都是public abstract

  4. 属性都是public static final

  5. 接口不能被实例化,没有构造方法

  6. implements可以实现多个接口

  7. 必须重写接口中的方法

内部类及OOP实战

1、内部类

  • 内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B而言就是外部类。

1⃣️成员内部类

public class Outer {
   private int id=10;
   public void out(){
       System.out.println("外部类方法");
  }
​
   public class Inner{
       public void in(){
           System.out.println("这是内部类方法");
      }
​
       //
       public void getID(){
           System.out.println(id);
      }
  }
}
public class app {
   public static void main(String[] args) {
       Outer outer = new Outer();
       Outer.Inner inner=outer.new Inner();
       inner.in();
       inner.getID();
  }
}
​
/*
输出结果:
     这是内部类方法
     10
*/

2⃣️静态内部类

public class Outer {
   private int id=10;
   public void out(){
       System.out.println("外部类方法");
  }
​
   public class Inner{
       public void in(){
           System.out.println("这是内部类方法");
      }
​
       //
       public static void getID(){
           System.out.println(id);//报错,静态方法无法获取id(非静态变量)
      }
  }
}
public class Outer {
   private int id=10;
   public void out(){
       System.out.println("外部类方法");
  }
}
​
//一个Java文件里面可以有多个class类,但只能有一个public class
class Inner{
   public void in(){
  }
}

3⃣️局部内部类

public class Outer {
   private int id=10;
​
   //局部内部类
   public void out(){
    class Inner{
        public void in(){}
    }
  }
}

4⃣️匿名内部类

public class Outer {
   public static void main(String[] args) {
       //没有名字初始化类
       new Inner().in();
       new User(){
           @Override
           public void hello() {
​
          }
      };
  }
}
class Inner{
   public void in(){
       System.out.println("1");
  }
}
​
interface User{
   void hello();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TomYoung45

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值