首页 > 其他 > 详细

面向对象基础

时间:2021-06-08 09:54:54      阅读:19      评论:0      收藏:0      [点我收藏+]

面向对象基础

1、初始面向对象

1.1 面向过程 & 面向对象

  • 面向过程思想:

    ? a. 步骤清晰简单,第一步做什么,第二部做什么...

    ? b. 面向过程适合处理一些较为简单的问题

  • 面向对象思想:

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

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

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

1.2 什么是面向对象

  • 面向对象编程(Object-Oriented Programming,OOP)
  • 面向对象编程的本质就是:以类的方式组织代码,以对象的方式组织(封装)数据。
  • 抽象
  • 三大特性:
    • 封装
    • 继承
    • 多态
  • 从认识论角度考虑是先有对象后有类。对象:是具体的事物;类:是抽象的,是对对象的抽象。
  • 从代码运行角度考虑是先有类后有对象。类是对象的模板;对象是类的具体实例。

2、方法回顾和加深

2.1 静态、非静态方法

public class Demo02 {

    public static void main(String[] args) {
        //静态方法的调用:类名.方法名
        //Student.say();

        //非静态方法的调用: 对象名.方法名
        Student student = new Student();
        student.say();
    }

    //静态方法:和类一起加载
    public static void a(){
       // b(); //程序报错!
    }

    //非静态方法:类实例化之后才存在
    public  void b(){
    }
}

//注意:一个类里面可以定义多个class,但只能存在一个public class
class Student{
    //属性:字段field  成员变量
    String name;
    //方法
    public void study(){
        System.out.println(name + "正在努力学习!");
    }
}

2.2 形参和实参

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

        Demo03 demo03 = new Demo03();

        //实参:调用方法时实际传给方法的数据
        int result = demo03.add(3, 5);
        System.out.println(result);

    }

    //形参:在方法被调用时用来接收输入的数据
    public  int add(int a,int b){
        return (a+b);
    }

}

2.3 值传递和引用传递

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

    //值传递
    public static void sub(int a){
        //返回值类型为空,并没有把10传递给main方法中的a变量
        a = 10;
    }

}
  • 引用传递:
//引用传递:对象,本质还是值传递。
//对象 , 内存!
public class Demo05 {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name); //null

        Demo05 demo05 = new Demo05();
        demo05.change(person);
        System.out.println(person.name); //亚洲杜兰特
    }

    public void change(Person person){
        person.name = "亚洲杜兰特";
    }

}

//一个类里面可以定义多个class,但只能有一个public class.
//定义了一个Persion类,有一个属性:name
class Person {
    String name; // null
}

3、对象的创建与内存分析

3.1 类与对象的关系

  • 类是一种抽象的数据类型,它是对某一事物整体描述/定义,但是并不能代表某一个具体的事物。
  • 对象是抽象概念的具体化实例。

3.2 创建于初始化对象

  • 使用new关键字创建对象

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

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

    • 必须和类的名字相同
    • 必须没有返回类型,也不能写void

    作用:<使用new关键字,本质是在调用构造方法。>

      1. **创建对象**
      2. **初始化成员变量的值**
    

技术分享图片

public class Person {
    //属性
    String name;
    int age;

    //显示的定义构造器
    //初始化对象的值
    public Person(){
        this.name = "老李";
    }

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

    //构造方法的重载
    public Person(int age) {
        this.age = age;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

3.3 创建对象的内存分析

public class Application{
	public static void main(String[] args){
        Pet dog = new Pet();
        dog.name = "旺财";
        dog.age = 2;
        
        Pet cat = new Pet();
       
    }    
}

class Pet {
    //属性
    public String name;
    public int age;

    //方法
    public void shout(){
        System.out.println(this.name + "叫了一声!");
    }

    //构造方法
    public Pet() {
    }

技术分享图片

小结:

? 栈:存放方法名和变量名(基本类型、引用类型变量名指向堆中对象的内存地址)

? 堆:对象的内存地址

? 方法区:静态方法区和类一起加载;常量池...

4、面向对象的三大特性!

4.1 封装

技术分享图片

  • 属性私有化:private

  • getter方法:获取这个属性的值,有返回值类型,无参数列表。

    ? public int getAge(){ return this.age; }

  • setter方法:设置这个属性的值,返回值类型为void,有参数列表。

    ? public void setAge(int age){ this.age = age; }

注意:getter和setter方法必须是public!

  **alt + insert: 快捷键,生成get、set方法**
//封装: 属性私有化  private		
//getter/setter
public class Student { 

    //属性私有 
    private int id; //学号 
    private int age; //年龄 

    //方法: public的get、set 
    //get(): 获取当前属性的值 有返回值 无形参 
    public int getId(){
       return this.id; 
    } 

    //set(): 设置当前属性的值 返回值类型为void 有形参 
    public void setId(int id){ 
      this.id = id; 
  }
}


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

4.2 继承

技术分享图片

4.2.1 子类(派生类)、父类(基类)、Object类

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

  • Java中,只有单继承,没有多继承。

    <即子类只能直接继承一个父类,间接继承父类的基类;而父类可以有多个子类。>

  • final关键字修饰的类不能被继承!

  • 修饰符的优先级顺序:

    public > protected > default > private

  • 子类继承父类:就会拥有父类的全部public方法以及非private属性;(也就是:私有的东西无法被继承。)

  • Ctrl + H :打开继承树

4.2.2 this、super关键字

super注意点:    
    1.super调用父类的构造方法,必须在构造方法的第一行    
    2.super 必须只能出现在子类的方法或者构造方法中    
    3.super和 this不能同时调用构造方法!(因为两者都必须写在构造方法的第一行)
VS  this:      
      代表的对象不同:         
        this:本身调用者这个对象(当前类的对象)         
        super:代表父类对象的引用      
      前提:         
        this:没有继承,也可以使用        
        super:只有在继承条件下,才可以使用      
      构造方法:         
        this();  当前类的构造         
        super(); 父类的构造
//Person 人 :父类,基类
public class Persion{    
    //属性:protected 受保护的    
    protected String name = "KevinDurant";     
   
    //无参构造器    
    public Person(){        
      System.out.println("父类-Person无参构造方法执行了!");    
    }        

    //有参构造器: 定义有参构造器时,默认的无参构造器必须显示定义出来,否则就不存在!    
    public Person(String name){        
      this.name = name;    
    }	
}

//Schokastic 学生,学者  is a 人 :派生类,子类//子类继承父类,就会拥有父类的全部public方法、public属性!
class Scholastic extends Person{    
    //私有属性:    
    private String name = "KD35";    

    //无参构造    
    public Scholastic(){        
    //隐藏代码,创建子类对象scholastic时,会调用父类的无参构造方法。        
    super(); //调用父类的构造方法,而且必须写在子类构造方法的第一行,否则程序报错!        
    //super(name) //调用父类的有参构造方法,也是必须在子类构造方法的第一行。        
    System.out.println("子类-Scholastic无参构造方法执行了!");    
    }    

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

    public void test1(){        
      print(); //Person        
      this.print(); //Person        
      super.print(); //Scholastic    
    }   

    public void test(String name){        
      System.out.println(name); //凯文·杜兰特        
      System.out.println(this.name); //KD35        
      System.out.println(super.name); //KevinDurant    
    }
}

4.2.3 方法重写:Override

public class Applycation{    
    public static main(String[] args){    
/*       
    静态方法和非静态方法的区别很大:         
      静态方法:方法的调用只和左边定义的数据类型有关         
      非静态方法:重写Override    
*/        
    B b = new B();        
    b.test(); // B=>test.                
    //父类型引用指向子类型对象        
    A a = new B();        
    a.test(); // B=>test.    
  }
}

class A{    
    public void test(){        
      System.out.println("A=>test.");    
    }
}

class B extends A{    
    //重写父类的test()    
    public void test(){        
      System.out.println("B=>test");    
    }
}

方法重写:有继承关系的子类重写其父类的方法。

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

即:子类的方法和父类必须一致,方法体不同。

为什么要重写?

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

alt + insert : Override

4.3 多态

技术分享图片

补充:

  1. 引用类型转换:

    ? 向上转型:自动类型转换; (父类 ---> 子类)

    ? 向下转型:强制转换,需要加强制类型转换符,可能会丢失一些方法; (子类 ---> 父类)

    类型转换异常:ClassCastException!

  2. 以下关键字修饰的方法没有多态:

    ? a. static 静态方法,属于类,不属于实例
    ? b. final 常量,在常量池中
    c. private方法

instanceof:

? x instanceof Y

? ①两边的类要有关系(属于继承/同一类),编译时才能通过; <编译时多态>

? ②判断创建的对象,是否为Y类或其子类的实例;若是,返回true;否则返回false。 <运行时多态>

public class Applycation{    
    //main() 程序执行的入口    
    public static void main(String[] args){       
    //父类型引用指向子类对象        
    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        
    //Object、Teacher类具有继承关系,因此编译时能通过;但实际创建的new Student()与			
    //Teacher没有父子类关系,返回false。        
    System.out.println(object instanceof Teacher); //false                

    Person person = new Student();                
    //编译报错:Person和String类之间不具有继承关系!        
    //System.out.println(person instanceof String);         
    System.out.println(person instanceof Student); //true        
    System.out.println(person instanceof Person); //true        
    System.out.println(Person instanceof Object); //true            
    }
}

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

class Student extends Person{

}

class Teacher extends Person{

}

5、static用法:

5.1 静态变量和非静态变量

5.1.1 静态变量定义和调用

  • 静态变量:使用static修饰的变量,属于类变量。

  • 调用:

    ①类名.静态变量名(在同一类下时,类名.可省略)

    ②对象名.静态变量名

5.1.2 非静态变量定义和调用

  • 非静态变量:不用static加以修饰的变量。
  • 调用:对象名.变量名
//Chef:厨师
//静态变量和非静态变量的定义、调用
public class Chef {    
    private static int age; //静态变量/类变量    
    private String name; //非静态变量、成员变量
   
    public static void main(String[] args){        
      Chef chef = new Chef();        
      System.out.println(Chef.age); //类名.静态变量名        
      System.out.println(chef.name); //对象名.变量名        
      System.out.println(chef.age); //对象名.静态变量名    
    }
}

5.2 静态方法和非静态方法

5.2.1 静态方法的定义和调用

  • 静态方法:static修饰的方法

  • 调用:

    ? 类名.方法名 (在同一类下时,类名.可省略)

5.2.2 非静态方法的定义和调用

  • 非静态方法:不用static修饰的方法

  • 调用:

    ? 对象名.方法名

5.3 静态代码块

匿名代码块、静态代码块、构造方法的执行顺序:

public class Animals {    
    {        
      //匿名代码块:没有名字,不能被调用;创建对象时在构造器之前自动调用。        
      System.out.println("匿名代码块");  // ②    
    }    

    static{        
      //静态代码块:用于加载一些初始化的数据;跟随类加载执行,且永久只执行一次!        
      System.out.println("静态代码块");   // ①    
    }    

    public Animals(){        
      System.out.println("无参构造器");  // ③    
    }    

    public static void main(String[] args){        
      Animals anmals1 = new Animals();        
      System.out.println("-------------------------");        
      Animals animals2 = new Animals();    
    }
}

5.4 静态导入包

//静态导入包:方便直接调用random();
import static java.lang.Math.random;
public class Test {    
    public static void main(String[] args) {   
     
      //数学工具类Math下的random(): 生成一个随机数。        
      System.out.println(random());    

    }
}

注意:static关键字不能用在方法体内;(否则程序报错!)

? 只能用在类里面,修饰变量和方法。

6、抽象类和接口

6.1 抽象类

  • 抽象类:abstract约束~的类;

    ? ①不能new这个抽象类,只能靠子类来实现它;约束!

    ? ②抽象类中可以写普通方法

    ? ③抽象方法必须在抽象类中

  • 抽象方法:abstract约束的方法;

    ? 只有方法的名字,没有方法的实现。(没有方法体)

//abstract:抽象类: 类 extends  单继承~  (接口可以实现多继承)
class abstract Action{    
    //抽象方法    
    public abstract void doSomething();        

    //普通方法    
    public void run(){            
    
    }
}

//抽象类中的所有抽象方法,都需要被继承它的子类来实现!
class A extends Action{    

    public void doSomething(){        
    System.out.println("实现父类中的抽象方法。");    
    }

}

6.2 接口Interface!

技术分享图片

  • 接口是一种约束、规范!
  • 利用接口可以实现多继承
  • 接口方法都是:public abstract方法
  • 接口成员变量都是静态常量:public static final
  • 接口不是类,不能被实例化,且没有构造方法
  • implement 可以实现多个接口,但必须要重写接口中的方法

7、内部类

7.1 什么是内部类?

  • 内部类就是在一个类的内部再定义一个类。比如:A类中定义一个B类,那么B类相对A类来说称为内部类,而A类相对B类来说就是外部类。
  • 内部类可以获取外部类中的私有属性、私有方法!

7.2 成员内部类

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

    //成员内部类    
    public class Inner{        
      public void out(){            
        System.out.println("这是内部类方法");        
      }                
    
      //获取外部类私有属性        
      public void getAge(){            
        System.out.println(age);        
      } 
           
    }        

    //main():程序的入口    
    public static void main(String[] args){        
      //创建外部类对象        
      Outer outer = new Outer();        
      //创建内部类对象:通过外部类来实例化内部类        
      Outer.Inner inner = outer.new Outer();        
      inner.getAge();    
    }    
}

7.3 静态内部类

public class Outer{        
    //静态内部类:static class    
    public static class Inner{            

    }    
}

7.4 局部内部类

public class Outer{        
    public void method(){        
      //局部内部类: 写在方法里面的类        
      class Inner{            
        public void in(){  }        
      }            
    }
}

7.5 匿名内部类

public class Test{    
    public static void main(String[] args){ 
       
      //匿名内部类:没有名字初始化类,不用将实例保存到变量中        
      new Apple().eat(); 
               
      //实现接口的匿名内部类        
      new UserService(){            
        public void hello(){                
          System.out.println("hello");            
        }       
      }; 
           
    }
}

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

interface UserService{    
    void hello();
}

面向对象基础

原文:https://www.cnblogs.com/lyq-9726/p/14861125.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!