09 面向对象

面向对象

01什么是面向对象

  1. 面向对象编程(Object-Oriented Programming,OOP)

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

  3. 抽象

  4. 三大特性:封装,继承,多态

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

  6. 从代码运行角度考虑是先有类后有对象。类是对象的模板。

02 回顾方法的定义

package oop;

//Demo01就是一个类
public class Demo01 {

   //main方法
   public static void main(String[] args) {

  }

   /*
   修饰符 返回值类型 方法名(){
       方法体
       return 返回值;
   }
    */

   //return结束方法,返回一个结果(结果也可能为空)
   public String sayHello(){
       return "hello woeld";
  }

   public int max(int a,int b){
       return  a > b ? a : b; //三元运算符
  }

}

03 方法的调用

下面两个框框代码演示"静态方法"调用

package oop;
public class Demo02 {
   //静态方法 static
   public static void main(String[] args) {
       Student.say();
  }
}
package oop;
//学生类
public class Student {
   //静态方法
   public static void say(){
       System.out.println("学生说话了");
  }
}

下面两个框框代码演示"非静态方法"调用

package oop;
public class Demo02 {
   //非静态方法 带有static
   public static void main(String[] args) {
       //实例化这个类 new
       //对象类型 对象名 = 对象值
       //new Student().say();因为有人这样写
       Student student = new Student();//一般这样写
       student.say();
  }
}
package oop;
//学生类
public class Student {
   //非静态方法 不带static
   public void say(){
       System.out.println("学生说话了");
  }
}

同一个类中两个方法之间的调用

package oop;
public class Demo02 {
   //非静态方法 static
   public static void main(String[] args) {
       //实例化这个类 new
       //对象类型 对象名 = 对象值
       //new Student().say();因为有人这样写
       Student student = new Student();//一般这样写
       student.say();
  }

   //报错的原因看下边两个方法的注释

   //和类一起加载的
   public static void a(){
       b();
  }

   //类实例化之后才存在
   public void b(){

  }

}

实际参数与形式参数的类型要对应

package oop;

public class Demo03 {
   public static void main(String[] args) {
       int add = Demo03.add(1,2);
       System.out.println(add);
  }

   public static int add(int a,int b){
       return a+b;
  }


}

注意形式参数与实际参数的值传递

package oop;

//值传递
public class Demo04 {
   public static void main(String[] args) {
       int a = 1;
       System.out.println(a); //1

       Demo04.change(a);

       System.out.println(a); //1
  }

   //返回值为空
   public static void change(int a){
       a = 10;
  }
}

引用传递

package oop;

//引用传递 传递一个对象, 本质还是值传递
//现在听晕了,原因是还不了解 对象 和 内存
public class Demo05 {
   public static void main(String[] args) {
       Perosn perosn = new Perosn();
       System.out.println(perosn.name);  //null

       Demo05.change(perosn);
       System.out.println(perosn.name); //大佬
  }

   public static void change(Perosn perosn){
       perosn.name = "大佬";
  }
}

//定义了一个Perosn类,有一个属性:name
class Perosn{
   String name;  //null
}

04 类与对象的关系

  1. 类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。 动物、植物、手机、电脑. Person类、Pet类、Car类等,这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为

  2. 对象是抽象概念的具体实例 张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例。

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

创建与初始化对象

  1. 使用new关键字创建对象

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

  3. 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下俩个特点: a.必须和类的名字相同 b.必须没有返回类型,也不能写void

    下边两个代码结合着看:

    package oppDemo02;

    //学生类
    public class Student {

       //属性 ; 字段
       String name;//null
       int age;//0

       //方法
       public void study(){
           System.out.println(this.name+"在学习");
      }
    }
    package oppDemo02;

    //一个项目应该值存一个main方法
    public class Application {
       public static void main(String[] args) {

           //类:抽象的,实例化
           //类实例化后会返回一个自己的对象
           //student对象就是一个Student类的具体实例
           Student student = new Student();
           Student xiaoming = new Student();
           Student xiaohong = new Student();

           xiaoming.name = "xiaoming";
           xiaoming.age = 3;

           System.out.println(xiaoming.name);
           System.out.println(xiaoming.age);

           xiaohong.name = "xiaohong";
           xiaohong.age = 3;

           System.out.println(xiaohong.name);
           System.out.println(xiaohong.age);
      }
    }

     

  4. 构造器必须要掌握

05 构造器

 

package oppDemo02;

public class Person {
   //一个类就算什么也不写,也会存在一个方法
   //显示的定义构造器

   String name;

   //实例化初始值
   //1.使用new关键字,本质是在调用构造器
   //构造器用来初始化值
   public Person(){}

   //有参构造:一旦定义了有参构造,无参必须显示定义
   public Person(String name){
       this.name = name;
  }
}

// alt+insert可以生成构造器,选择第一个有参,第二个无参

/*
构造器:
   1. 和类名相同
   2.没有返回值
作用:
   1.new 本质在调用构造方法
   2.初始化对象的值
注意点:
   定义的有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
*/
package oppDemo02;

//一个项目应该值存一个main方法
public class Application {
   public static void main(String[] args) {
       //new实例了一个对象
       Person person = new Person("kuangshen");

       System.out.println(person.name);  //null
  }
}

06 创建对象内存分析

package oppDemo03;

public class Application {
   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);
       
       Pet cat = new Pet();
  }
}
package oppDemo03;

public class Pet {
   public String name;
   public int age;

   //无参构造

   public void shout(){
       System.out.println("叫了一声");
  }
}

image-20220306000043216


06 简单小结类与对象

package oppDemo03;

public class Application {
   public static void main(String[] args) {
       /*
       1.类与对象
           类是一个模板,抽象;对象是一个具体的实例
       2.方法
           定义,调用!
       3.对象的引用
           引用类型:八大基本类型
           对象是通过引用来操作的:栈--->堆
       4.属性: 字段Field 成员变量
           默认初始化:
               数字: 0 0.0
               char: u0000
               boolean: false
               引用: null

           修饰符 属性类型 属性名 = 属性值!
       5. 对象的创建和使用
           必须用new 关键字创造对象, 构造器 Person kuangshen = new Person()
           对象的属性:kuangshen.name
           对象的方法: liangshen。sleep()

       6.类:
           静态的属性   属性
           动态的行为   方法

       ‘封装,继承,多态’

        */
  }
}

08 封装

  1. 该露的露,该藏的藏 我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操细节自己完成,不允许外部

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

  3. 记住这句话就够了:属性私有,get/set

package oop;

import oop.Demo04.Student;

/*
1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.系统可维护性提高
*/

public class Application {
   public static void main(String[] args) {
       Student s1 = new Student();
       //s1.name   如果nam不是private而是public则不会报错

       s1.setName("秦疆");
       System.out.println(s1.getName());
  }
}
package oop.Demo04;

//类 private:私有
public class Student {
   //属性私有
   private String name;    //名字
   private int ID; //学号
   private char sex; //性别

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

   //get 获得这个数据
   public String getName(){
       return this.name;
  }
   //set 给这个数据设置值
   public void setName(String name){
       this.name = name;
  }

   // alt+insert
}

09 继承

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

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

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

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

  5. 继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。

  6. 子类和父类之间,从意义上讲应该具有"is a"的关系.

  7. object类

  8. super

  9. 方法重写

package oop.Demo05;

//人 父类
public class Person {

   //public(继承推荐这个方法)
   //protect
   //default
   //private
   public int money = 10_0000_0000;//如果把public改为private(私有的),则子类不能调用
   public void say(){
       System.out.println("说了一句话");

  }
}
package oop.Demo05;

//学生 is 人   派生类
//子类继承了父类,就会拥有父类的全部方法
public class Student extends Person{

   // Ctrl + H 继承树

}
package oop;

import oop.Demo05.Student;

public class Application {
   public static void main(String[] args) {
       Student student = new Student();
       student.say();
       System.out.println(student.money);
  }
}

10 Super详解

package oop.Demo05;

//学生 is 人   派生类
//子类继承了父类,就会拥有父类的全部方法
public class Student extends Person{
   private String name = "qinjiang";

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

   public void test1(String name){
       print();
       this.print();
       super.print();
  }

   public void test(String name){
       System.out.println(name); //秦将
       System.out.println(this.name); //qinjiang
       System.out.println(super.name);//kuangshen
  }
}
package oop.Demo05;

//人 父类
public class Person {

   protected String name = "kuangshen";

   public void print(){
       System.out.println("person");
  }
}
package oop;

import oop.Demo05.Student;

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

       Student student = new Student();
       student.test("秦将");
  }
}

//【狂神说Java】Java零基础学习视频通俗易懂哔哩哔哩bilibili

11 方法重写

package oop.Demo05;

public class A extends B{
   public static void test(){
       System.out.println("A=>test()");
  }
}
package oop.Demo05;

//重写都是方法的重写和属性无关
public class B {
   public static void test(){
       System.out.println("B=>test(");
  }
}
package oop;

import oop.Demo05.A;
import oop.Demo05.B;

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

       //方法的调用只与左边有关
       A a = new A();
       a.test();//A

       //父类的引用指向了子类
       B b = new A();
       b.test();//B
  }
}

重写

package oop.Demo05;

public class A extends B{
   //override 重写
   @Override//注解:有功能的注解
   public void test() {
       super.test();
  }
}

package oop.Demo05;

//重写都是方法的重写和属性无关
public class B {
   public  void test(){
       System.out.println("B=>test(");
  }
}
package oop;

import oop.Demo05.A;
import oop.Demo05.B;

public class Application {

   //静态方法和非静态方法区别很大
       //静态方法只和左边有关
   //非静态: 重写
   public static void main(String[] args) {

       //方法的调用只与左边有关
       A a = new A();
       a.test();//A

       //父类的引用指向了子类
       B b = new A();
       b.test();//B
  }
}
  1. super注意点: 1.super调用父类的构造方法,必须在构造方法的第一个

    2.super 必须只能出现在子类的方法或者构造方法中! 3.super和this不能同时调用构造方法!

  2. Vs this:

    代表的对象不同:

    this:本身调用者这个对象 super:代表父类对象的应用 前提 this:没哟继承也可以使用 super:只能在继承条件才可以使用

    构造方法

    this();本类的构造 super():父类的构造!

  3. 重写:需要有继承关系,子类重写父类的方法! 1·方法名必须相同 2.参数列表列表必须相同 3.修饰符:范围可以扩大胆不能缩小:public>Protected>Default>private 4.抛出的异常:范围,可以被缩小,但不能扩大;ClassNotFoundException--> Exception(大)

  4. 重写,子类的方法和父类必要一致;方法体不同!

  5. 为什么需要重写: 1,父类的功能,子类不一定需要,或者不一定满足! Alt + Insert;override;


12 多态

  1. 动态编译:类型:[可扩展性

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

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

  4. 多态存在的条件 有继承关系 子类重写父类方法 父类引用指向子类对象

  5. 注意:多态是方法的多态,属性没有多态性。

  6. instanceof

package oop.Demo06;

public class Person {

   public void run(){
       System.out.println("run");
  }
}
package oop.Demo06;

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

import oop.Demo06.Person;
import oop.Demo06.Student;

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

       //可以指向的引用类型就不确定了: 父类的引用指向子类

       //Student 能调用的方法都是自己的或者继承父类的
       Student s1 = new Student();
       //person 父类 ,可以指向子类,但是不能调用子类独有的方法
       Person s2 = new Student();
       Object s3 = new Student();

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

       //对象能执行哪些方法主要看左边,和右边的关系不大
       s1.eat();
       //s2.eat(); 报错
  }

}

多态注意事项: 1多态是方法的多态,属性没有多态 2父类和子类,有联系 类型转换异常!ClassCastException! 3存在条件:继承关系,方法需要重写,父类引用指向子类对象!Fathen f1 = new Son();

1.static 方法,属于类,它不属于实例 2.final 常量; 3.private方法;


13 instanceof和类型转换

instanceof 可以判断两个类型之间是否存在父子关系

package oop.Demo06;

public class Teacher extends Person{
}
package oop.Demo06;

public class Person {

   public void run(){
       System.out.println("run");
  }
}
package oop;

import oop.Demo06.Person;
import oop.Demo06.Student;
import oop.Demo06.Teacher;

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

       //Object-->Person-->Student
       Object object = new Student();

       System.out.println(object instanceof Student);//1
       System.out.println(object instanceof Person);//1
       System.out.println(object instanceof Object);//1
       System.out.println(object instanceof Teacher);//0
       System.out.println(object instanceof String);//0
  }
}

(类型转换)

package oop.Demo06;

public class Person {

   public void run(){
       System.out.println("run");
  }
}
package oop.Demo06;

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

   public void go() {
       System.out.println("go");
  }
}
package oop;

import oop.Demo06.Person;
import oop.Demo06.Student;

public class Application {
   public static void main(String[] args) {
       //类型之间的转换: 父--子
       //高---------------------低
       Person obj = new Student();

       //将Person换为student类型,我们就可以使用student类型的方法了
       //高转低需要强制转换
       Student student = (Student) obj;
       student.go();
//     上面两行也可以这样写 ((Student) obj).go();
  }
}

1.父类引用指向子类的对象 2.把子类转换为父类,向上转型; 3.把父类转换为子类,向下转型;强制转换

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

封装、继承、多态! 抽象类,接口


14static关键字详解

package oop.Demo07;

//Static
public class Student {
   private static int age; //静态变量
   private double score;  //非静态变量

   public void run(){

  }

   public static void go(){

  }

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

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


       new Student().run();
       Student.go();
       go();
  }
}
package oop.Demo07;

public class Person {
//   {
//       //代码块(匿名代码块)
//   }

  {
       System.out.println("匿名代码块");
  }


//   static {
//       //静态代码块
//   }
   static {
       System.out.println("静态代码块");
  }

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

   public static void main(String[] args) {
       Person person = new Person();
       System.out.println("=========");
       Person person1 = new Person();
  }
}
package oop.Demo07;
//静态导入包
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());
       System.out.println(random());
       System.out.println(PI);
  }
}

15抽象类

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

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

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

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

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

package oop.Demo08;

//abstract 抽象类本质是个类 extends:单继承。   但接口可以多继承
public abstract class Action {

   //约束   有人帮我们实现 (只有方法的名字,没有方法的实现)
   public abstract void dosomething();//如果方法中有抽象方法,则类必须是抽象类

   // 1.不能new这个抽象类,只能考子类去实现它: 约束!
   //2.抽象类中可以写普通的方法
   //3.抽象方法必须在抽象类中
   //抽象的抽象: 约束
}
package oop.Demo08;

//抽象类的所有方法,继承了他的子类,都必须要实现他的方法
public class A extends Action{
   @Override
   public void dosomething() {

  }
}
package oop;

import oop.Demo06.Person;
import oop.Demo06.Student;
import oop.Demo08.A;
import oop.Demo08.Action;

public class Application {
   public static void main(String[] args) {
//       new Action(); //报错
       A a = new A();
  }
}

16 接口

  1. 普通类:只有具体实现

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

  3. 接口:只有规范! 自己无法写方法 ~ 专业的约束! 约束和实现分离:面向接口编程。

  4. 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你好人,则必须干掉坏人:如果你是坏人,则必须欺负好人。

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

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

package oop.Demo09;

//抽象的思维~~java架构师

//interface 定义的关键字 , 接口都需要实现类
public interface UserService {
   //接口中的所有定义都是抽象的 public abstract
//   public void run(); 报错:接口里边不让写方法

   //一般这样写
   void add(String name);
   void delete(String name);
   void update(String name);
   void query(String name);
}
package oop.Demo09;

public interface TimeService {
   void timer();
}
package oop.Demo09;

//抽象类: extends
//类 可以实现接口 implements 接口
// 实现了接口的类,就必须重写接口中的方法

//多继承~利用接口实现多继承
public class UserServiceImpl implements UserService,TimeService{
   @Override
   public void add(String name) {

  }

   @Override
   public void delete(String name) {

  }

   @Override
   public void update(String name) {

  }

   @Override
   public void query(String name) {

  }

   @Override
   public void timer() {

  }
}

作用:I 1.约束 2.定义一些方法,让不同的人实现~ 103.public abstract 4.public static final5,接口不能被实例化~,接口中没有构造方法~ 6.implements可以实现多个接口 7.必须要重写接口中的方法~ 8.总结博客~


17 n种内部类

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

2.静态内部类

3.局部内部类

4.匿名内部类

package oop.Demo10;

public class Outer {

   private int id;
   public void out(){
       System.out.println("这是外部类的方法");
  }

   public class Inner{
       public void in(){
//       public static void in(){ 这样子下边就没办法访问了
           System.out.println("这是一个内部类");
      }

       //获得外部类的私有属性
       public void getID(){
           System.out.println(id);   //如果上边加入static这个id就访问不到了
      }

  }
}
package oop;

import oop.Demo10.Outer;

public class Application {
   public static void main(String[] args) {
       //new
       Outer outer = new Outer();

       //通过这个外部类来实例化内部类
       Outer.Inner inner = outer.new Inner();
       inner.in();
  }
}

【狂神说Java】Java零基础学习视频通俗易懂哔哩哔哩bilibili

 

posted @ 2022-03-06 19:57  CHPang  阅读(104)  评论(0)    收藏  举报