面向对象

本文详细介绍了面向对象编程的基本概念,包括面向过程与面向对象的区别、类与对象的定义、成员变量和方法、构造方法、访问权限修饰符、静态与非静态成员、单例模式、继承、多态等核心概念。通过Java代码示例,阐述了类的创建、对象的实例化以及如何使用静态和非静态成员。此外,还讨论了包的管理、导入、访问权限控制以及代码块的作用。面向对象编程能够提高代码的复用性和可扩展性,是软件开发中的重要设计思想。
摘要由CSDN通过智能技术生成

面向对象

面向过程语言设计思想

过程:具体步骤

把要完成的一件事情,分成一步一步的步骤,然后完成。

面向过程直接关注流程。

例如:开车

1.开车门()

2.坐进去()

3.关车门()

4.插钥匙()

5.踩油门()

面向对象语言设计思想

首先会宏观的对整个事物进行分析(分类),不关心具体要做什么,而是关心谁(对象)去做。

汽车

开门()

关门()

钥匙()

油门()

操作()

先有对象,后有类

对象:指的是一个具体存在的。

特点:1.以分类的方式进行思考和解决问题。

2.面向对象先对整体关系作出分类,然后根据不同的类深入细节的处理。

3.面向对象的思想符合人类的认知习惯。

面向对象与面向过程的区别与联系

面向对象无法取代面向过程,他们是相辅相成的。面向对象关注于从宏观上把握事物之间的关系,在具体到如何实现某个细节时,仍然采用面向过 程的思维方式。面向对象如果离开了面向过程,就无法实现真正的落地,成为无源之水。

Java类

什么是类?

类就是对同一类事物(具体存在的)共有的属性(名词)、行为(动词)的定义(抽象)。

类是一个模板,它描述一类事物的属性和行为的集合。

根据某个类,来创建这个类的具体实例(对象)

类是表示一个客观世界某类群体的特征抽象。

发现类(设计类)

类的结构

成员变量:事物属性的描述;

方法:事物的行为(可以做的事情) ;

构造方法:用于创建对象;

内部类: 即在类体中声明的类;

块:一段没有名称的代码块。

Java对象

对象是类的实例,是概念的具体存在,以类为模板,在内存中创建一个真实存在的实例。

万事万物皆为对象(可以使用的)

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

        /*
        new 使用new关键字创建一个新的对象
        new Car    创建Car类的对象
        Car()   使用类的构造方法初始化类
        Car bm 声明一个与构造方法相同的类型的变量
        = 把内存中对象存储的地址  赋值给左边的  bm变量
         */
        Car bm = new Car();
        bm.name = "宝马";
        bm.color = "黑色";
        bm.price = 400000f;
        bm.run();
        bm.stop();

        Car bc = new Car();
        bc.name = "奔驰";
        bc.color = "白色";
        bc.price = 5000000f;
        bc.run();
        bc.stop();
    }
}
/*
  发现类
  汽车类:
     [访问权限修饰符][修饰符] class 类名{

     }
 */
public class Car {
    /*
    成员变量       类的属性
    修饰符  类型  变量名 = [值]
     */
    //public final String name;
    //static String name;
    String name;
    String color;
    float  price;
    /*
    成员方法   类的行为(动词)
    访问权限修饰符 返回值类/void 方法名(参数类型 参数名){
        [return 值]
    }
     */

    //行驶
    public void run(){
        System.out.println("汽车行驶");
    }

    //刹车
    public void stop(){
        System.out.println("汽车刹车");
    }
}

类中的变量

从数据类型角度分:

基本类型变量:byte int short long float double char boolean

引用类型变量:类 数组 接口等

按照位置来划分:

成员变量:直接被类所包含的变量

​ 成员变量的数据类型可以为基本类型,也可以为引用类型

​ 可以对成员变量进行初始化的赋值(不建议),如果不初始化,在创建对象时,可以调用构造方法使用默认值赋值

​ 成员变量可以被类中的方法,构造方法,特定类的语句块进行访问

​ 成员变量生命周期:变量什么时候生(对象创建),什么时候死(对象被回收时)

局部变量:在方法(成员方法,构造方法)中或者在代码块中包含的

​ 局部变量在使用之前必需进行显示的初始化赋值

​ 局部变量的生命周期:变量什么时候生(方法被调用时),什么时候死(方法运行结束 出栈)

类中的方法

成员方法:[非static修饰]被对象调用,完成对象的功能(行为),定义在类中

修饰符 返回值类型 方法名 ( 参数列表) { 

方法体语句; 

[return 返回值] 

} 

构造方法:用来初始化创建出来的对象.例如为对象中的属性进行赋值

方法名与类名相同,没有返回值,不需要void修饰

每一个类中至少有一个默认无参的构造方法,每次创建对象时至少调用一个.如果显示的定义一个构造方法,默认的就失效了.

方法重载:在一个类中,有多个方法的名称相同.

方法的区分:通过参数区分:参数个数不同,类型,顺序.

方法的重载与方法返回值类型无关

普通的成员方法的可以构成方法重载

//无参数构造方法
public Car(){
    System.out.println("无参的构造方法");
}

//有参的构造方法
public Car(String n,String c){
    name = n;
    color = c;
    System.out.println("有参的构造方法,String n,String c");
}
public Car(String n,float f){
    name = n;
    price = f;
    System.out.println("有参的构造方法,String n,float f");
}
public Car(float f,String n){
    name = n;
    price = f;
    System.out.println("有参的构造方法,String n,float f");
}

public Car(String n,String c,float f){
    name = n;
    color = c;
    price = f;
    System.out.println("有参的构造方法,String n,String c,float f");
}

对象与引用

java中的数据类型:

基本类型:byte short int long…简单类型

引用类型:除了基本类型都是引用类型,用类作为类型的都是引用类型,数组int a[]也是引用类型 也称为复合类型/复杂类型

为什么叫引用类型?

引用类型变量并不是持有对象本身,知识拥有对象的地址,通过地址间接访问对象.

//创建对象
Car car = new Car();
//对Car car = new Car();的解释
/*右边的“new Car()”,是以Car类为模板,调用Car类的构造函数,在堆空间里创建一个Car类对象。
左边的“Car car”创建了一个Car类型引用变量。所谓Car类的引用,就是以后可以用来指向Car 对象的对象引用。
”=”操作符使对象引用指向刚创建的那个Car对象。 我们可以把这条语句拆成两部分: Car car; car= new Car(); 这样写,就比较清楚了,有两个实体:一是对象引用变量,一是对象本身。
*/

引用类型

数组,接口,类

他的值是对象在空间中的地址,具体对的对象存在堆中

值传递与引用传递

public class Test2 {

    public static void main(String[] args) {

        Dog xh = new Dog();
            xh.name = "小黑";

        Test2 t = new Test2();
              t.test(xh);
        System.out.println("xh=" +xh.name);//旺财
    }

    //引用类型传递时并不是将对象本身传递,只是将对象引用地址,这样形参发生变化,实参也会发生变化,因为两个指向的是同一个对象
    public void test(Dog dog){
        System.out.println("dog1=" +dog.name);//小黑
        dog.name = "旺财";
        System.out.println("dog2=" +dog.name);//旺财
    }

}

static关键字

概念

static被称为静态,可以用来修饰成员变量,类的属性,方法,代码块,内部类.

static修饰的成员的特点

随着类的加载而加载

优先于对象存在

修饰的成员,被所有的类所共享

可以不创建对象,直接被类所调用

static属性:静态属性是类的所有对象共享的,即不管创建了多少个对象,静态属性在内存中只有一个.

public class Chinese{ 
    //非静态属性
    String name ;//姓名 
    //静态属性
    static String country;//国家 

} 

static方法可以使用对象调用,也可以直接用类名调用,建议用类名直接调用.

在static方法内部只能访问类的static属性,不能访问类的非static属性,static属 性先加载。

public class Monimaipiao {

    private static int ticket = 11;
    public static void sellticket(){
        ticket = ticket - 1;
        System.out.println("卖票的静态方法!!!");
    }

    public static void main(String[] args) {
        Monimaipiao.sellticket();
    }
}
public class TestStaticMethod {

    String name;//非静态的是在创建对象时加载
    static int num = 10;

    /**
     * static修饰的方法随着类的加载而加载,static方法属于类,
     * 但也可以被对象调用,建议使用类名static方法中不能使用非静态方变量,
     * 因为静态的内容是先加载.
     */
    public static void test() {
        //System.out.println(name);//不能使用非静态的.
        System.out.println(num);
    }

    //非静态的成员方法中,可以使用静态的成员变量
    public void test1() {
        System.out.println(num);
    }

    public static void main(String[] args) {

        TestStaticMethod.test();
        TestStaticMethod t = new TestStaticMethod();
        t.test1();
    }
}

代码块

代码块在类中声明,类似一个没有名称的方法体(代码块),代码分实例块和静态块

//实例快:每次创建对象时自动调用执行
{
    //任何符合语法的java代码
}
//静态块:类加载时自动调用执行,仅一次,与是否创建对象无关
static{
    //任何符合语法的java代码
}
/*代码块定义在类中,没有名称,分为实例代码块和静态代码块
       实例块在创建对象时调用,每创建一次对象调用一次

静态代码块在类被加载时被调用,只执行一次.
       类被加载时:第一次创建对象,实用类中的静态变量,静态方法
*/
public class Student {

    public final static int n = 10;

    /*
    成员变量
     */

  static   int num;
   static String name;
    static String country = "中国";

    //代码块定义在类中,没有名称,分为实例代码块和静态代码块
    //实例块在创建对象时调用,每创建一次对象调用一次
    {
        System.out.println("实例代码块1!!!");
    }
    {
        System.out.println("实例代码块2!!!");
    }

    //静态代码块在类被加载时被调用,只执行一次.
    //类被加载时:第一次创建对象,实用类中的静态变量,静态方法
    static {
        System.out.println("静态代码块1!!!");
    }
    static {
        System.out.println("静态代码块2!!!");
    }

    public Student(){
        System.out.println("无参构造方法!!!");
    }
    public Student(int n, String na){
        num = n;
        name = na;
    }

    /*
    成员方法
     */
    public static void showInfo(){
        System.out.println("学号"+num+"\t姓名"+name);
    }

}
public class Test {

    public static void main(String[] args) {

        Student student1 = new Student();
        Student student2 = new Student();

        System.out.println(Student.country);
        Student.showInfo();
    }
}

类中元素的加载顺序

先加载静态的,静态的内容按照先后顺序进行加载

实例代码块

构造方法

包的概念

就是文件夹(从文件系统的角度来讲)

包的作用

按照不同的功能管理类 不同的模块 用户模块 部门模块 按照功能划分数据库连接 工具类…

避免类重名(每个包里面的类的功能、作用是不同的)

//从java角度来讲,包是类的路径,位置
//严格意义上的类名:全类名 = 包名 + 类的名称
import java.util.Date;//import 类的地址
//import java.sql.Date;

public class Test {

    public static void main(String[] args) {
        new Date(12);
        new java.sql.Date(1000);
        new Date();
    }
}

控制访问权限(访问权限修饰符)

java.long包中的类在使用时不需要导入,使用其他包中的类时,需要使用import关键字导入.

访问权限修饰符

java语言有四个访问权限修饰符,权限从大到小依次为:

public:公共权限 修饰类,属性,方法.可以被任意类访问

protected:受保护的权限 修饰方法,属性 可以被同包类访问,如果不是同包类,必须是该类的子类才能访问

(defalut):同包权限 修饰类,方法,属性.只能被同包的类访问

private:私有权限 修饰方法,属性. 只能在本类中访问

包(package)的命名规范:

在包名中,可以使用.号来区分包的级别;包名一般情况下是小写

第一级 指该项目的类型,如com,org,gov等,

第二级 指项目所开发或者运行的公司名称,如:oracle,sun,huawei

第三级 指项目的名称,如:bcms,oa,erp,cms等

第四级 指项目模块的名称,如:bean,action,exception等

包可以更好得管理逻辑相关的类,可以控制不同包之间的访问权限

导入外部包的类,关键字"import".

面向对象的特征

封装

概念:将类的某些信息隐藏在类内部(权限问题),不允许外部程序直接访问, 而是通过该类提供特定的方法来实现对隐藏信息的操作和访问 。

优点:1.只能通过规定方法访问

​ 2.隐藏类的实现细节

​ 3.方便加入控制语句

​ 4.方便修改实现

public class Person {

    private String name;
    private int age;
    private static Person person = null;

    public void SetName(String n) {
        if (n != null || n.length() < 10) {
            name = n;
        }
    }

    public String getName(){
        return name;
    }

    public int getAge(){
        return age;
    }

    public void SetAge(int a) {
        if (age >= 0 && age < 120) {
            age = a;
        }
    }
    
    /*
    单例模式:在一个引用程序中,只能创建一个对象
    public Person(){

    }

     public static  Person getPerson(){
        if (person!=null) {
            person = new Person();
        }
        return person;
    }*/
}
public class TestPerson {

    public static void main(String[] args) {

        Person p1 = new Person();
               p1.SetName("asdfgh");
               p1.SetAge(18);

        System.out.println(p1.getName());
        System.out.println(p1.getAge());
    }
}

继承

概念:继承是面向对象程序设计不可缺少的设计思想,是实现代码可重用的根基,是提高代码可扩展性的主要途径。

继承是从已有的类中派生出新的类,新的类能吸收已有类的属性和行为,并能扩展新的能力。

在JAVA中使用extends关键字来表示继承关系。

JAVA支持多继承,单继承使JAVA的继承关系很简单,一个类只能有一个直接父类。

继承之后子类可以调用父类的所有非私有属性和非私有方法.

优点: 提高代码的复用性

继承使用场景

Student Dog Car Pseron

Dog 继承 Car

Car 继承 Dog

Dog 继承 Animal

Student 继承 Person

Teacher 继承 Person

继承是面向对象程序设计思想,提高代码的重用性,可扩展性

/*
   设计一个动物类   父类  基类
   当一个类没有显示的继承其他类的时候,此时这个类默认继承Object
   Object类是java中所有类的基类(父类  超类)

 */
//public class Animal extends Object{
public class Animal{

           private String  name;
           private int age;

           public Animal(){
                super();
                System.out.println("Animal无参构造");
           }

           void  eat(){
               System.out.println("动物吃东西");
           }

           public  void sleep(){
               System.out.println("动物睡觉");
           }


           public String getName() {
            return name;
           }

           public void setName(String name) {
            this.name = name;
           }

           public int getAge() {
            return age;
           }

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


/*
  设计Dog类
   狗是动物   继承Animal  拥有父类中行为属性(非私有的)
   java中的继承:一个类只能直接继承一个父类
   Dog extends Animal 显示的继承   extends Object

 */
public class Dog extends Animal{

         private String type;
         //无参构造
         public Dog(){
          super();
          System.out.println("Dog无参构造");
        }
        //有参构造
        public Dog(String type){
             super();
             this.type=type;
            System.out.println("Dog有参构造");
        }

        public  void play(){
              System.out.println("1111");
              System.out.println(super.getName()+"狗会玩");
        }

        //构造方法,静态方法不能被重写,  属性也不存在重写,
        //当父类中实现方式(代码) 不能满足子类中的需求,可以在子类中将父类中的方法重写(方法覆盖 覆写)
        @Override//java中的注解标签  说明 此方法是从父类中重写过来的  在编译期间就会对语法进行校验
        void eat() {
            System.out.println("ssssss");//子类自己的实现方式
            System.out.println("ssssss");
            //super.eat();//调用父类的实现
            super.sleep();
            System.out.println("ssssss");
            System.out.println("ssssss");
        }

        public String getType() {
                return type;
        }

        public void setType(String type) {
                this.type = type;
        }
}


public class XiaoTianQuan extends  Dog{

       public XiaoTianQuan(){
          // super();//super() 表示调用父类的构造方法
         //  super("牧羊犬");//调用父类的构造方法 默认调用(默认存在) 
           //如果使用super()显示的调用,则必须方法构造方法的第一行
           System.out.println("XiaoTianQuan无参构造");
       }

       public  void  fly(){
           System.out.println("哮天犬会飞");
       }
}


public class Test {
    public static void main(String[] args) {
         Dog wc  = new Dog();
            wc.sleep();
            wc.eat();
            wc.setName("旺财");
            wc.setAge(5);
        System.out.println(wc.getName());
        System.out.println(wc.getAge());

            wc.setType("牧羊犬");
            wc.play();
        System.out.println(wc.getType());

            wc.hashCode();

        System.out.println("============================");
            XiaoTianQuan xtq  = new XiaoTianQuan();
                         xtq.hashCode();//Object

                         xtq.setName("哮天犬");//Animal
                         xtq.setAge(500);

                         xtq.play();//Dog

                         xtq.fly();//自己
    }
}

public class Test1 {
    public static void main(String[] args) {
        /*
          构造方法作用:初始化类的成员
         */
        XiaoTianQuan xtq = new XiaoTianQuan();
          // xtq.eat();

        /*
            当创建一个子类对象时,会在子类的构造方法中调用父类的构造方法,先去初始化父类.
                            默认会在构造方法的第一行使用super()调用
                            如果显示的使用使用super()调用,也必须在第一行,
                            可以使用super()传参,调用指定的构造方法
         */
    }
}

public class Test2 {

    public static void main(String[] args) {
        Dog wc = new Dog();
            wc.setName("旺财");
            wc.play();

            wc.eat(); //此时 wc 调用的是Dog类中重写的eat()
            wc.sleep();
    }
}

多态

概念:同一种事物,在不同时刻表现不同的状态

存在的三个必要条件:

1.要有继承(包括接口的实现)(前提条件)

2.要有重写(前提条件)

3.父类引用指向子类对象

Object obj  = new Car();
       obj  = new Dog();
       obj  = new Cat();

多态环境下的调用

1.成员方法:编译看左边,运行看右边

2.静态方法:编译和运行都看左边

3.成员变量:编译和运行都看等号左边

方法参数具有多态性的好处:提高代码的扩展性

转型的作用:1.向上转型:提高程序的扩展型.

​ 2.向下转型:为了使用子类中的特有方法.

this关键字

this关键字代表自身类的对象(this表示对象)

​ 使用this关键字可以应用成员变量

​ 使用this关键字可以引用成员方法

注意:this关键字必须放在非静态的方法里面

public void SetName(String name) {
    if (name != null || name.length() < 10) {
        //this表示当前正在操作的对象
        this.name = name;
    }
}
public void SetAge(int age) {
        if (age >= 0 && age < 120) {
            this.age = age;
    }
}

在一个类的方法或构造方法内部,可以使用“this.成员变量名”这样的 格式来引用成员变量名,常常用来区分同名的成员变量和局部变量。

public class Student {

    public final static int n = 10;

    /*成员变量*/
    int num;
    String name;

    public Student(){

    }
    public  Student(int n,String na){
        this.num = n;
        this.name = na;
    }

    /*成员方法*/
    public void showInfo(){
        System.out.println("学号"+num+"\t姓名"+name);
    }
}

单例模式

/*
设计模式:前人总结出解决某一类问题的方法
       单例模式:在整个应用程序的运行过程中只创建一个对象
 */
public class WindowDemo {

    static WindowDemo windowDemo=null;
    //构造方法私有化
    private WindowDemo(){

    }
    /*
    向外界提供的获得对象的方法
     */
    public static WindowDemo getWindowDemo(){
        //控制只生成一个对象
        if (windowDemo ==null){
            windowDemo = new WindowDemo();
        }
        return windowDemo;
    }

}

抽象类

/*
 如果一个类中没有包含足够的信息(抽象方法)来描绘一个具体的对象,这样的类就是抽象 类。
 抽象类中可以没有抽象方法,有抽象方法必定是抽象类
 一般用在体系结构的顶层用来进行功能的定义声明

 */
public abstract class Animal {

     int num;

     /*
       抽象类可以拥有构造方法,但是不能创建对象
      */
     public Animal(){
         System.out.println("Animal无参构造");
     }

    /*
    *抽象方法:只有方法声明, 没有方法体,也就是没有具体的实现
    */
    public abstract void eat();//在比较顶级的类中就可以定义一个方法即可

     public void sleeep(){
         System.out.println("动物睡觉");
     }
}

/*
  一个类如果继承了抽象类
     要么重写抽象类中所有的抽象方法
     要么将该类也定义为抽象类
 */
//public abstract class Dog extends Animal {
public  class Dog extends Animal {

    public  Dog(){
        super();
    }

    @Override
    public void eat() {
        System.out.println("狗吃东西");
    }
}


public class Test {

    public static void main(String[] args) {
        Dog dog = new Dog();

        System.out.println(dog.num);
        dog.eat();
        dog.sleeep();
    }
}

final关键字

用于声明属性,方法和类

属性:定义就必须直接赋值或者在构造方法中进行赋值,并且后期都不能修改.

方法:子类里不可以重写.

类:不能被定义为抽象类或者接口,不可以被继承.

final属性赋值

1.在声明时同时赋值,往往与static一起使用

2.声明时不赋值,必须在构造方法中注意赋值

总的原则:保证创建每一个对象的时候,final属性的值是确定的.

public class FinalDemo {

    /*
    总体原则:
    保证创建每一个对象的 时候,final属性的值是确定的。
     */
    //final属性赋值:在声明时同时赋值,往往与 static一起使用。
    static final int PI = 3;

    //在声明时如果不赋值,则必须在构造方法中进行赋值
    final int num;

    public FinalDemo(int n) {
        num = n;
    }


    public static void main(String[] args) {

        FinalDemo finalDemo1 = new FinalDemo(10);

        FinalDemo finalDemo2 = new FinalDemo(20);

        System.out.println(finalDemo1.num);

        System.out.println(finalDemo2.num);
    }
}
public class Demo extends FinalDemo {

    public Demo(int n) {
        super(n);
    }
}

接口

接口的定义和使用

定义:使用interface关键字用来声明一个接口

[访问修饰符] interface 接口名称 [extends 其他的接口名1,.其他的接口名n] 

{ 

// 声明常量 抽象方法 静态方法 默认方法 

}

使用:类使用implements关键字实现接口。在类声明中,Implements关 键字放在class声明后面。

[访问修饰符] class 类名 implements 接口名1,接口名2……{ 


} 

结合继承

[访问修饰符] class 类名 extends 父类名 implements 接口名1,接口名2……{ 
    
}
public class MyInterfaceImpl implements MyInerface{

    public static void main(String[] args) {

        MyInterfaceImpl myInterface = new MyInterfaceImpl();

        myInterface.eat();

        myInterface.sleep();

        myInterface.test1();

    }

    @Override
    public void eat(){
        System.out.println("eat!!!!!!!");
    }

    @Override
    public void test1() {
        System.out.println("test1!!!!!");
    }


    @Override
    public void sleep(){
        System.out.println("sleep!!!!!!");
    }

}
public interface MyInerface {
    int NUM = 10;

    //public abstract void eat();
    void eat();
    void sleep();

    //默认方法
    default void test1(){
        System.out.println("默认方法!!!");
    }

    //静态方法
    static void test2(){
        System.out.println("静态方法!!!");
    }

}

接口的特性

接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。

接口中方法可以是抽象的,静态的,默认的。

接口中声明的属性默认为 public static final 的;

接口不是被类继承了,而是要被类实现。

接口不能实例化对象(无构造方法),但可以声明对象的引用。(多态性)

多个类可以实现同一个接口。

一个类可以实现多个接口,但只能继承一个类。

与继承关系类似,接口与实现类之间存在多态性。

一个接口能继承其它多个接口。

当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明 为抽象的类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值