面向对象编程

源自视频课程的本人总结,推荐课程链接

初识面向对象

面向过程&面向对象

面向过程:线性思维,方法的每一步
面向对象:分类思维,分类思考,多人协作
描述复杂事物时,从宏观把握,从整体上合理分析,需要使用面向对象思路分析。但是,具体到微观操作,仍需面向过程的思路处理。

面向对象

  1. 本质:以类的方式组织代码,以对象的组织(封装)数据
  2. 三大特性:封装、继承、多肽;
  3. 对象是具体的事物,类是抽象的,是对对象的抽象;
  4. 从代码运行的角度考虑是先有类后有对象。

方法回顾和加深

方法的定义

  1. 格式:修饰符 返回类型 方法名 (参数列表)
  2. break和return的区别:break跳出switch,结束循环;return结束方法
  3. 方法名命名规则,见名知意
  4. 抛出异常

方法的调用

  1. 类方法调用
    • 非静态类方法调用,实例化对象:对象类型 对象名 = 对象值
      在这里插入图片描述
    • 静态类方法调用,添加修饰符static
      在这里插入图片描述
    • static和类一起加载,非静态方法需要类实例化之后才存在
    package com.OOP.demo01;
    public class Demo01 {
    		//和类一起加载的
     	public static void a(){
     	//        b();  //错误
     	}
     	//实例化后才存在的
    	 public void b(){
    
     	}
     }
    
  2. 形参和实参
  3. 值传递和引用传递
    • 值传递
    package com.OOP.demo01;
    
    public class Demo02 {
    	public static void main(String[] args) {
        	int a = 1;
        	System.out.println(a);  //1
    
        	Demo02.change(a);  //传递的是值,方法中未返回值
        	System.out.println(a);  //1
    	}
    
    	//返回值为空
    	public static void change(int a){
        	a = 10;
    	}
    }
    
    • 引用传递
    package com.OOP.demo01;
    
    //引用传递:对象,本质还是值传递
    public class Demo03 {
    	public static void main(String[] args) {
        	Person person = new Person(); //类实例化
        	System.out.println(person.name);  //null
    
        	Demo03.change(person);
        	System.out.println(person.name);  //ada  ?   改变了对象的值
    	}
    	public static void change(Person person){
        	person.name = "ada";
    	}
    }
    
    //定义一个Person类,有一个属性:name
    class Person{
    	String name;  //默认null
    }
    

对象的创建分析

  1. 创建一个Student类
package com.OOP.demo02;

//学生类
public class Student {
    //属性:字段
    String name;  //默认null
    int age;   //默认0

    //方法
    public void study(){
        System.out.println(this.name+"在学习");
    }
}
  1. 实例化类,返回一个对象(创建一个对象)
package com.OOP.demo02;

//一个项目应该只存在一个main()方法
public class Application {
    public static void main(String[] args) {
        //类是抽象的
        //类实例化返回一个自己的对象
        //xiaoming对象就是Student类的一个具体实例
        Student xiaoming = new Student();
        Student xh = new Student();

        //赋值
        xiaoming.name  = "小明";
        xiaoming.age = 10;
        xh.name = "小红";
        xh.age = 20;

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

类的构造器

  1. 特点:①必须和类的名字相同;②必须没有返回类型,也不能写void
  2. 类构造器分为有参和无参两种;当没有有参构造器时,类中默认有一个无参构造器;当类中有一个或几个有参构造器时,如果想使用无参构造器必须显示定义一个无参的构造,否则new实例化时,类中要有参数,不然报错。
  3. new本质是在调用构造方法;初始化对象的值
  4. 快捷键:Alt+Insert—构造器(有参或无参)
  5. this.name = name; 前一个name指的是属性,后一个name指的是赋值
    • 构造器
    package com.OOP.demo02;
    
    public class Person {
    	//一个类即使什么都不写,它也存在一个方法-构造方法
    	//构造方法(不能有返回类型或void,必须与类名一致)
    	public Person(){
    
    	}
    
    	String name;
    	int age;
    	//构造方法分为有参和无参
    	//当类中有有参构造器时,若想保留无参构造器,则必须显示地写出无参构造器
    	//有参构造器
    	public Person(String name, int age){
        	this.name = name;
        	this.age = age;
    	}
    }
    
    • main测试
    package com.OOP.demo02;
    
    //一个项目应该只存在一个main()方法
    public class Application {
    	public static void main(String[] args) {
        	//new实例化
        	Person person = new Person();
    
        	person.name = "asd";
        	System.out.println(person.name);
    	}
    }
    

创建对象的内存分析

代码对比分析
在这里插入图片描述
在这里插入图片描述
实例化同一个类Pet()的两个对象dog、cat,而内存中对象作为引用变量分别创建对象类

总结类与对象

  1. 类与对象
    类是一个模版,抽象的;对象是具体的实例;
  2. 方法的定义与调用 修饰符 返回类型 方法名(参数列表){}
  3. 对象的引用:引用类型,基本类型(8);对象是通过引用实现操作,引用指向的是地址;
  4. 属性,字段
    • 默认值:int ->0;String -->null;char–>u0000;boolean–>false; 引用–>null
  5. 对象的创建和使用
    • 使用new创建对象,构造器(类名和方法名同);Person person = new Person()
    • 对象的属性 person.name
    • 对象的方法 person.sleep()
    • 静态的属性 属性
    • 动态的行为 方法

面向对象三大特性

封装

  1. 特点:高内聚,低耦合;
    • 高内聚就是类的内部数据操作细节自己完成,不允许外部干涉
    • 低耦合,仅暴露 少量的方法给外部使用
  2. 封装关键字:private
  3. 封装的作用:
    • 提高程序的安全性,保护数据
    • 隐藏代码实现细节
    • 统一接口
    • 易于维护系统
  4. 代码示例:
    • 封装类
    package com.OOP.demo04;
    
    public class Student {
       //封装:属性私有private
       private String name;
       private String sex;
       private int age;
    
       //定义get、set供外面访问
       public String getName() {
           return this.name;
       }
       public void setName(String name){
           this.name = name;
       }
       // Alt  + Insert  自动生成所有属性的get、set
       public String getSex() {
           return sex;
       }
    
       public int getAge() {
           return age;
       }
    
       public void setSex(String sex) {
           this.sex = sex;
       }
       
       //保证数据安全性
       public void setAge(int age) {
           if (age>120 || age <= 0){
               this.age = 3;
           }else{
               this.age = age;
           }
       }
    }
    
    
    • main测试
    package com.OOP.demo02;
    
    import com.OOP.demo04.Student;
    //一个项目应该只存在一个main()方法
    public class Application {
       public static void main(String[] args) {
           //实例化对象
           Student student = new Student();
           student.setName("小明");
           student.setAge(9999);  //不合法
    
           System.out.println(student.getName());  //小明
           System.out.println(student.getAge());  //3
       }
    }
    

继承

  1. 继承的本质就是对某一批类的抽象
  2. 继承:extends表示“扩展”。子类就是父类的扩展;父类私有属性和方法无法被子类继承
  3. Java中类只有单继承,没有多继承;即每个子类只能有一个父类
  4. 类与类之间的关系有:继承、依赖、组合、聚合等
  5. object类:理论上,所有的类都继承于object类
    示例:
    • 对比效果(源码粘在下面)
      在这里插入图片描述
    • 父类-Person
    package com.OOP.demo05;
    
     public class Person {
     		//方法
     		public void shout(){
     		        System.out.println("你说话了!");
     		}
     }
    
    • 子类-Student
    package com.OOP.demo05;
    
    public class Student extends Person {
    
    }
    
    • main测试
    package com.OOP.demo02;
    
    import com.OOP.demo05.Student;
    
    //一个项目应该只存在一个main()方法
    public class Application {
        public static void main(String[] args) {
            //实例化对象
            Student student = new Student();
            student.shout();
        }
    }
    
继承之Super
  1. 子类调用父类属性或方法(非private)时,用Super,super只能用在方法或构造方法里;调用本类属性或方法时,用this;**super()和this不能同时用在构造方法里。

A. 示例1对比效果(属性):
在这里插入图片描述
源码:

  • 父类
package com.OOP.demo05;

public class Person {
    protected String name = "kkkk";

}
  • 子类
package com.OOP.demo05;

public class Student extends Person {
    String name = "abdd";

    public void test1(){
        System.out.println(name);  //abdd
        System.out.println(this.name);  //abdd
        System.out.println(super.name);  //kkkk
    }
}
  • main测试
package com.OOP.demo02;

	import com.OOP.demo05.Student;
	
	//一个项目应该只存在一个main()方法
	public class Application {
	    public static void main(String[] args) {
	        //实例化对象
	        Student student = new Student();
	        student.test1();
	    }
	}

B. 示例2对比效果(方法):
在这里插入图片描述
源码:

  • 父类
package com.OOP.demo05;

public class Person {
    public void print(){
        System.out.println("Person写!");
    }
}
  • 子类
package com.OOP.demo05;

public class Student extends Person {
    public void print(){
        System.out.println("Student写!");
    }
    public void test2(){
        print();  //子类
        this.print();   //子类
        super.print();  //父类
    }
    /* 输出结果
    Student写!
    Student写!
    Person写!
     */
}
  • main测试
package com.OOP.demo02;

import com.OOP.demo05.Student;

//一个项目应该只存在一个main()方法
public class Application {
    public static void main(String[] args) {
        //实例化对象
        Student student = new Student();
        student.test2();
    }
}
  1. 子类的无参构造中,默认调用父类无参构造;super()必须写在构造中的第一行

示例对比效果:
在这里插入图片描述

源码:

  • 父类
package com.OOP.demo05;

import sun.print.PeekGraphics;

public class Person {
    public Person(){
        System.out.println("person执行无参!");
    }
}
  • 子类
package com.OOP.demo05;

public class Student extends Person {
    public Student(){
        //默认执行了Super()
        super();   //super()和this必须写第一行
        System.out.println("student执行无参!");
    }
    /*执行结果
    student执行无参!
    person执行无参!
    */
}
  • main测试
package com.OOP.demo02;

import com.OOP.demo05.Student;

//一个项目应该只存在一个main()方法
public class Application {
    public static void main(String[] args) {
        //实例化对象
        Student student = new Student();
    }
}
  1. this VS super
    • 代表的对象不同:
      this:本身调用者这个对象
      super:代表父类对象的引用
    • 前提:
      this:没有继承也可以使用
      super:只能在继承的条件下菜可以使用
    • 构造方法
      this():本类的构造
      super():父类的构造
继承之重写
  1. 父类和子类中的static类方法调用
    A. 效果对比:
    在这里插入图片描述
    B.源码:
    • 父类
    package com.OOP.demo06;
    
     public class B {
         public static void test(){
             System.out.println("B==>test");
         }
     }
    
    • 子类
    package com.OOP.demo06;
    
     public class A extends B {
         public static void test(){
             System.out.println("A==>test");
         }
     }
    
    • main测试
    package com.OOP.demo02;
    
     import com.OOP.demo06.A;
     import com.OOP.demo06.B;
     
     public class Application {
         public static void main(String[] args) {
             //实例化对象
             //方法的调用只和左边(数据类型)有关
             A a = new A();
             a.test();   //A==>test
     
             B b = new A();
             b.test();   //B==>test
         }
     }
    
  2. 重写:①继承关系;②子类对父类非静态方法的重写
    A.效果对比
    在这里插入图片描述
    B.源码:
    • 父类
    package com.OOP.demo06;
    
     public class B {
         public void test(){
             System.out.println("B==>test");
         }
     }
    
    • 子类
    package com.OOP.demo06;
    
     public class A extends B {
         @Override  //Override 重写
         public void test() {
             super.test();
         }
     }
    
    • main测试
    package com.OOP.demo02;
    
     import com.OOP.demo06.A;
     import com.OOP.demo06.B;
     
     public class Application {
         public static void main(String[] args) {
             //实例化对象
             A a = new A();
             a.test();   //A==>test
     
             //父类的引用指向了子类
             B b = new A();  //子类重写了父类的方法
             b.test();   //A==>test
         }
     }
    
  3. 总结
    • 重写需要有继承关系,子类重写父类的方法
    • 重写方法的子类和父类的方法名必须相同
    • 修饰符:范围可以扩大但不能缩小; public>protected>default>private
    • 抛出异常:范围可以缩小,但不能扩大; ClassNotFoundException —> Exception(大)
    • 重写的作用:父类的功能,子类不一定需要,或者不一定满足;
    • Alt+ Insert; override

多态

  1. 多态是方法的多态,属性没有多态
  2. 父类和子类要有联系;类型转换异常,ClassCastException
  3. 多态存在的条件:继承关系、方法需要重写、父类引用指向子类对象;Father f1 = new Son();
  4. 子类能调用的方法都是自己的或者继承父类的
  5. 父类可以指向子类,但不能调用子类独有的方法
  6. 方便方法的调用,较少重复的代码
  7. 父类->子类,需强制转换;子类 ->父类,自动转换(可以会丢失自己本来的一些方法)
    A. 效果对比
    在这里插入图片描述
    B.源码:
    • 父类
    package com.OOP.demo07;
    
     public class Person {
         public void run(){
             System.out.println("person run");
         }
     }
    
    • 子类
    package com.OOP.demo07;
    
     import com.OOP.demo07.Person;
     
     public class Student extends Person {
         @Override
         public void run() {
             System.out.println("student run");
         }
     }
    
    • main测试
    package com.OOP.demo02;
    
     import com.OOP.demo07.Person;
     import com.OOP.demo07.Student;
     
     public class Application {
         public static void main(String[] args) {
             //一个对象的实际类型是确定的
             //但是它可以指向的引用类型时不确定的:父类引用指向子类
             Student s1 = new Student();
             Person s2 = new Student();
             Object s3 = new Student();
     
             s1.run();  //student run
             s2.run();  //student run 子类重写了父类方法,执行子类方法
         }
     }
    
instanceof和类型转换
  1. instanceof:System.out.println(X instanceof Y) -> (1)X与Y是否存在关系(编译错误);(2)X是否是Y的子类(是true否false)
    示例:父类Person,子类Student和Teacher
package com.OOP;

import com.OOP.demo07.Person;
import com.OOP.demo07.Student;
import com.OOP.demo07.Teacher;

public class Application {
    public static void main(String[] args) {
        //Object -> String
        //Object -> Person -> Teacher
        //Object -> Person -> Student
        Object object = new Student();

        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与String是同级
        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("==================");
        //instanceof比较的是两边有关系的,无关系的会报编译错误
        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. 类型转换:父类(高)、子类(低);低到高自动转换,高到低强制转换
    示例:
package com.OOP;

import com.OOP.demo07.Person;
import com.OOP.demo07.Student;
import com.OOP.demo07.Teacher;

public class Application {
    public static void main(String[] args) {
        Person student = new Student();
        //强制类型转换  -> (类型)
        ((Student) student).go();  
    }
}
static关键字
  1. 静态变量或静态方法与类一起加载,且只执行一次
  2. 静态导入包(不常用,了解)
  3. final关键字,final修饰的类不能被继承,即无子类
    示例1:静态变量
public class Application {
    //静态变量
    private static int age;
    private double score;

    public static void main(String[] args) {
        Application application = new Application();
        System.out.println(application.age);
        System.out.println(application.score);  //对象调用score
        System.out.println(Application.age);
        //非静态变量 调用类变量 编译错误;实例化为对象,才可调用
//        System.out.println(Application.score);   
    }
}

示例2:静态方法

public class Application {
    public void run(){
        go();   //方法里也可以直接调用静态方法
    }
    
    public static void go(){
        
    }

    public static void main(String[] args) {
//        Application.run();   //编译错误,非静态类方法
        //实例化后。就可调用非静态方法
        Application application = new Application();
        application.run();
        Application.go();   //静态方法在类定义时就加载了
    }
}

示例3:匿名代码块(2)、静态代码块(1)和构造方法(3)

public class Person {
    //2
    {
        System.out.println("匿名代码块");
    }
    //1,且只执行一次
    static {
        System.out.println("静态代码块");
    }
    //3
    public Person(){
        System.out.println("构造方法");
    }

    //main
    public static void main(String[] args) {
        Person person1 = new Person();
        System.out.println("=================");
        Person person2 = new Person();
        /* 运行结果
        静态代码块
        匿名代码块
        构造方法
        =================
        匿名代码块
        构造方法
         */
    }
}

示例4:导入包

//静态导入包
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);
    }
}

抽象类和接口

  1. 抽象类:
    • 不能new抽象类,只能靠子类去实现它(约束)
    • 抽象类里可以写普通的方法
    • 抽象方法必须写在抽象类里
    • 继承了含抽象方法的抽象类的子类必须要重写抽象方法,除非子类也是抽象类
//抽象类
public abstract class Action {
   //抽象方法,只有方法名,无方法实现,由子类实现override
   public abstract void  doSomthing();
   //构造器方法
   public Action(){
       System.out.println("抽象类的构造方法!");
   }
   //普通方法
   public void Speak(){
       
   }
}

子类继承实现抽象类中的抽象方法的重写:extends

public class C extends Action{
    @Override
    public void doSomthing() {
        
    }
}
  1. 接口:
    • 定义接口关键字:interface,接口都需要实现类
    • 接口的实现类可以实现多继承
    • 接口中的所有方法定义都是抽象的public abstract;常量定义:public static final
    • 接口不能被实例化。接口中没有构造方法
    • 实现类中用关键字:implements,必须重写接口中定义的所有方法override
  • 接口1:
public interface UserService {
    //增删改查,省略了public abstract
    void add();
    void delete();
    void update();
    void query();
}
  • 接口2:
public interface TimeService {
    void timer();
}
  • 实现类:implements
public class UserServiceImpl implements UserService,TimeService{
    @Override
    public void timer() {

    }

    @Override
    public void add() {

    }

    @Override
    public void delete() {

    }

    @Override
    public void update() {

    }

    @Override
    public void query() {

    }
}

内部类

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值