zoukankan      html  css  js  c++  java
  • Java学习之路(四):面向对象

    Java中的面向对象

    概念:面向对象的原本的意思是“”万物皆对象“”

    面向对象思想的特点:

    • 是一种更符合我们思想习惯的思想,将复杂的事情简单化
    • 使我们角色发生了转换,将我们从执行者变成了指挥者

    面向对象的特征:

    • 封装(Encapsulation)
    • 继承(Inheritance)
    • 多态(Polymorphism)

    一些专业性的词汇:

    • 面向对象的分析(OOA,Object Oriented Analysis)
    • 面向对象的设计(OOD,Object Oriented Design)
    • 面向对象的编程实现(OOP,Object Oriented Programming)

    面向对象的开发或者说面向对象的编程的本质就是不断的创建对象,使用对象,指挥对象做事情,管理和维护对象之间的关系


     面向对象的基本概念

      对象就是指人们要进行研究的世界上的任何事物,从最简单的整数到复杂的飞机...均都可以看做是一个对象,它不仅仅能表示具体的事物,还能抽象的规则、计划或事件

    如何描述现实世界的事物

    • 属性:就是该事物的描述信息(事物身上的名词)
    • 行为:就是该事物能够做什么(事物身上的动词)

    Java中最基本的单位是类,Java中是用class来描述一件事物

    • 类中有成员变量,就是事物的属性

    • 类中有成员方法,就是事物的行为

    其实我们学习java是学些什么?就是学习面向对象
        声明类
        声明成员变量
        声明成员方法
        创建对象
        给属性赋值
        使用对象

    类和对象的概念

    • 类:是一组相关的属性和行为的集合
    • 对象:是该类事物的具体体现
    • 注意:其实一个class类实例化后就是一个对象了

    类、属相和方法的声明

    • 类的声明:class关键字,eg:class Student
    • 属性的声明:数据类型  属性名,eg:String  name
    • 方法的声明:public  返回值类型  方法名(){ }
    //声明一个学生类
    //属性:姓名,年龄,性别
    //行为:学习,睡觉
    
    class Student{
        String name;
        int age;
        boolean sex;
        public void study(){
            System.out.println("这里是学习方法")
        }
        public void sleep(){
            System.out.println("这里是睡觉方法")
        }
    }

    类的使用

    • 创建对象:类名  对象名 = new 类名();
    • 给属性赋值:对象名.变量名
    • 调用方法:对象名.方法名()

    Java中的垃圾回收机制

    Java会自动回收无用的对象占用的内存空间,使该空间可以被程序再次使用,程序员不需要向C语言一样要自己进行释放内存的空间,CFRelease()

    成员变量和局部变量之间的区别

    • 在类中的位置不同
      • 成员变量:在类之中,方法之外
      • 局部变量:实在方法中定义的
    • 在内存中的位置不同
      • 成员变量:在堆内存(成员变量属于对象,对象进堆内存)
      • 局部变量:位于栈内存(局部变量属于方法,方法进入栈内存)
    • 声明周期不同
      • 成员变量:随着对象的创建而存在,随着对象的消失而消失
      • 局部变量:对着方法的调用而存在,随着方法的调用完毕而消失
    • 初始化的值不同
      • 成员变量:有默认的初始化值
      • 局部变量:没有默认的初始化值,必须定义,赋值然后才能使用

    成员变量和局部变量的注意事项:

      局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则

    基本数据类型(传值)和引用数据类型(传地址)有哪些?

    1.基本数据类型:byte,short,int,long,float,double,boolean,char

    2.引用数据类型:数组(eg:int[]),类(class),接口(interface),枚举

    方法的形式参数是一个类名的适合如何调用?

      如果你看到一个方法形式参数是一个类类型(引用类型)的话,那么调用方法的时候其实需要的是该类的对象。

    匿名对象

    什么是匿名对象:没有给新创建的对象储存在一个变量里

    应用的场景:

      1.调用方法,仅仅只需要调用一次的时候、

      2.匿名对象可以作为实际的参数进行传递


    封装概述:

      是指隐藏对象的属性和实现细节,仅仅对外提供公用的public访问方式

    封装好处:

    • 隐藏实现的细节,提供公共的访问方式
    • 提高了代码的复用性和安全性

    封装原则:

    • 封装原则将不需要对外提供的内容都隐藏起来
    • 把属性隐藏,提供公共的方法对其访问

    Private(私有)关键字

    • 是一个权限修饰符
    • 可以修饰成员变量和成员方法
    • 被其修饰的成员只能在本类中被访问

    当成员变量用private修饰表示外界不能访问

    this关键字的特点

    • 代表当前对象的引用

    this的应用场景

    • 用来区分成员变量和局部变量的重名

    this是和外面调用的变量指向同一个地址的,指的是同一对象。

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

    像这样,再构造方法中的应用就是最好的例子。

    如果你不加this,你可以试一下,会有很好玩的事情发生。

    构造方法Constructor的概述

    构造方法的作用:给对象的数据(属性)进行初始化的一个赋值

    构造方法的特点:

    • 方法名与类名相同(大小也与类名一致)
    • 没有返回值类型,注意:void也不要写,什么都不写
    • 没有具体的返回值return 

    构造方法分为

    • 有参构造方法
    • 无参构造方法

    构造方法的重载:

      是指方法名相同,与返回值类型无关(构造方法没有返回值),只看参数列表

    构造方法的注意事项

    • 如果我们没有给出构造方法,那么系统会默认给出一个无参数的构造方法
    • 如果我们给出了构造方法,系统将不在提供默认的无参构造方法
    • 如果我们声明的有参构造方法,这个时候。如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法。
    • 正确的构造方法的格式【public 类名()】

    static关键字

    static关键字的特点:

    • 随着类的加载而加载
    • static修饰的东西是优先于对象的存在
    • 被类的所有对象共享

    共性用静态,特性用非静态

    static声明的成员属性可以通过类名进行调用

    • 其实其本身也可以通过实例化的对象进行调用
    • 推荐使用类名进行调用
    • 静态修饰的内容我们一般称之为:与类相关的类成员

    注意事项:

    • static可以用来修饰属性,也可以用来修饰方法
    • 在静态方法中是没有this关键字的
      • 静态是随着类的加载而加载的,this则是随着对象的创建而进行创建的
      • 静态比对象要优先
    • 静态方法只能访问静态的成员变量和静态的成员方法
    • 非静态的方法可以访问静态的成员变量和静态的成员方法
    静态变量和成员变量的区别
    
    1.静态变量又叫类变量,成员变量又叫对象变量
    2.所属不同:
        静态变量属于类()
        成员变量属于对象,所以也称之为实例变量(对象变量)
    3.内存中的位置不同
        静态变量属于类,在方法区的静态区
        成员变量存储与堆内存
    4.内存出现时间不同
        静态变量随着类的加载而加载,随着类的消失而消失
        成员变量随着对象的创建而存在,随着对象的消失而消失
    5.调用不同
        静态变量可以通过类名调用,也可以通过对象调用
        成员变量只能通过对象调用

    代码块的概述:使用{}括起来的代码就称之为代码块

    代码块的分类:

    根据其位置和声明的不同,可以分为:

    • 局部代码块
    • 构造代码块
    • 静态代码块
    • 同步代码块(多线程)

    局部代码块:在方法中出现,限定变量的生命周期,及早释放,提高内存的利用率

    构造代码块:在类中方法外出现,多个构造方法中相同代码存放到一起,每次调用构造都执行,并且在构造方法前执行(注意了,构造代码块和构造方法可不是同一种东西)

    静态代码块(最常用):在类中方法外出现,并且要加上static修饰,用于给类进行初始化,在加载的时候就执行,并且只执行一次,一般用于加载驱动

    //局部代码块
    public class null01 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            {
                int a = 1;
                System.out.println(a);
            }//代码块执行结束,变量a被释放
        }
    
    }
    //构造代码块
    class
    Student{ String name; int age; public Student(){ name = "null"; age = 20; } { System.out.println("这就是构造代码块"); } } //每次都会执行,而且是优先于构造方法执行的
    //静态代码块
    class Student{
        String name;
        int age;
        public Student(){
            name = "null";
            age = 20;
        }
        {
            System.out.println("这就是构造代码块");
        }
        static{
            System.out.println("这里是静态代码块");
        }//在加载的时候就会执行,而且只会执行这一次。一般用于加载驱动
    }

    继承概述:让类与类之间产生关系,子父关系

    继承的好处:

    • 提高代码的复用性
    • 提高代码的维护性
    • 让类与类之间产生了关系,继承是多态的前提

    继承的弊端:

    • 类的耦合性增强了
    • 开发的原则:高内聚(自己完成某事),低耦合

    继承的特点:

    • Java只支持单继承,不支持多继承(关键字 extends)
    • Java支持多层继承
      • 如果想用这个体系的所有功能,我们有最底层的类来创建对象
      • 如果想用这个体系的共性功能,我们调用最顶层的类

    继承的注意事项:

    • 子类只能继承父类所有的非私有的成员(非私有的成语方法和成员变量)
    • 子类可以通过super关键字访问父类的东西

    super和this

    • super的作用:super指的是当前类的对象的父类引用
    • super可以调用父类的成员属性  super.成员变量
    • super可以调用父类的成员方法  super.成员方法
    • super可以调用父类的构造方法  super(...)
    • .
    • this的作用:this指的是当前类的对象引用
    • this可以调用本类的成员属性
    • this可以调用本类的成员方法
    • this可以调用父类的成员方法(在本类没有的情况下)  this.父类方法、this.父类属性
    • this可以调用本类的构造方法

    继承中的构造方法的关系

    子类中的所有的构造方法默认都会访问父类中空参数的构造方法

      应为子类会继承父类中的数据,可能还会使用父类的数据,所以在子类的初始化之前,一定要用super首先要完成父类的初始化

      所以我们会发现,当我们利用Eclipse工具生成子类的构造方法时就会存在super()方法

    继承工构造方法的注意事项

    • 子类必须创建无参构造方法,内还要调用父类的构造方法
    • 子类实现有参构造方法
    • 父类自己实现无参构造方法
    • super()和this都是必须出现在构造方法的第一条语句上

    方法的重写

    指的是子类中出现和父类一模一样的方法。重写这个概念只存在与继承的父子之间

    应用场景:

      当子类需要父类的功能,而子类又有自己的特有内容的时候,可以重写父类中的方法。这样就可以即沿袭了父类的功能,有定义了子类特有的内容

    注意事项:

      父类中私有方法不能重写,因为父类私有方法子类根本就无法继承

      子类重写父类的时候,访问权限最好一致

    方法的重写与重载

    Overload是指方法的重载,重载可以改变返回值类型,方法的重载只看参数类表不同

    Override是指方法的重写,也就是子类中出现了和父类中方法声明一模一样的方法

    方法的重写与返回值类型有关,返回值是一致的(或者是子父类)的

    方法的重载,在本类中出现的方法名相同,参数列表不同。与返回值类型无关

    Final关键字修饰类,方法以及变量

    final修饰的特点:

    • 修饰类,类不能被继承
    • 修饰变量,变量就变成了常量,只能被赋值一次
    • 修饰方法,方法就不能被重写

    修饰变量:

    • final修饰变量叫常量,一般会与public static公用
    • 注:常量的变量名一定要全部大写

    final修饰局部变量:

    • 修饰基本类型,值不能被改变
    • 修饰引用类型,是地址不能被改变,对象中的属性可以改变
    • 修饰引用类型,那就不可以在new对象了

    多态的概述 

    什么是多态:事物的多种状态...

    Java中存在多态的前提条件:

    • 要有继承关系
    • 要有方法的重写
    • 要有父类引用指向子类对象(Father son = new Son())

    多态中的成员访问特点:

    • 成员变量:编译看左边(父类),运行看左边(父类)
    • 成员方法:编译看左边(父类),运行看右边(子类)
    • 静态方法:编译看左边(父类),运行看左边(父类)
    • 总结:只有非静态的成员方法,编译看左边,运行看右边

    注意:在多态的写法中,父类指向了子类,我们实例化然后调用一个方法是,这个方法在父类中必须存在,否则将会无法进行编译

    多态中的向上转型和向下转型

    • 向上转型:父类指向子类对象 Father p = new Son();
    • 向下转型:子类指向父类对象 Son son = (Son)p;

      向下转型注意:父类的真实对象必须是子类对象,否则会有问题

    多态的好处与弊端:

    • 提高了代码的维护性
    • 提高了代码的扩展性
    • 但是却不能使用子类的特有属性和行为

    抽象类的特点:

    • 抽象类和抽象方法必须用abstract关键字修饰
      • abstract class 类名{}
      • public abstract void eat();
    • 抽象类不一定有抽象方法,有抽象方法的类一定是个抽象类或者是接口
    • 抽象类不能实例化,要由具体的子类实例化。这也是多态的一种(抽象类多态)
    • 抽象类的子类:要么是抽象类,要么重写抽象类中所有的抽象方法

    抽象类的成员的特点:

    • 成员变量:既可以是变量,也可以是常量。
    • abstract不能修饰成员变量,只能修饰类和方法
    • 构造方法:抽象类也是有构造方法的,用于子类访问父类数据的初始化
    • 成员方法:抽象类的方法可以是抽象的,也可以是非抽象的

    抽象类的成员的特性:

    • 抽象方法:强制要求子类实现
    • 非抽象方法:子类可以继承实现

    接口

    • 从狭义的角度上将,就是指java中的interface关键字
    • 从广义上讲对外提供规则的都是接口
    • 接口就是提供对外访问的规则

    接口的特点:

    • 接口用关键字interface表示   interface 接口名{}
    • 类去实现接口用implements表示  class 类名  implements  接口名{}
    • 接口不能进行实例化
    • 接口的子类可以是抽象类(没有意义),一个具体的类,要重写接口中的所有方法

    类与类,类与接口,接口与接口的关系

    类与类:

      继承关系,只能是单继承,可以多层继承

    类与接口:

      实现关系,可以单实现,也可以多实现,并且还可以在继承一个类的同时实现多个接口

    接口与接口:

      继承关系,可以单继承,也可以多继承

    抽象类与接口的区别

    1.成员区别

    • 抽象类可以有成员变量,也可以有常量,构造方法,成员方法(抽象的和非抽象的)
    • 接口只能有变量,方法只能是抽象方法

    2.关系区别

    • 类与类:继承关系,单继承
    • 类与接口:实现关系,单实现和多实现均可
    • 接口与接口:继承关系,单继承与多继承

    3.设计理念的区别

    • 抽象类:抽象类中定义的是该继承体系的共性功能
    • 接口:接口中定义的是该继承体系的扩展功能

    package关键字的概述以及作用

    package包的作用:

    • 包其实就是文件夹
    • 包的作用是将字节码(.class)进行分类存放
    • 包的作用可以使在同一个项目中有相同的类
    • 包的作用有利于以后功能模块的划分

    包的格式的定义:

    • 包名一般使用公司域名的倒写

    包的类能被其他的包访问,那么这个包一定是public的类,public修饰的类代表其他包可以访问此类

    四中权限修饰符:
      private,default,protected,public

      所谓的权限就是别人是否能访问类、属性、方法

    用在类上的修饰符:default,public,final(状态修饰符),abstract(抽象修饰符)

    用在成员上的修饰符:权限修饰符(private,default,protected,public),状态修饰符(static,final)

    用在构造方法上的修饰符:权限修饰符(private,default,protected,public)

    用在成员方法上的修饰符:权限修饰符(private,default,protected,public),状态修饰符(static,final),抽象修饰符(abstract)

    protected关键字

    表示受保护的

    protected修饰的方法只能在当前包中访问,或者由子类访问

     内部类

    内部类的概述和访问特点

    • 内部类的概述:就是在class类的内部再定义一个class类
    • 内部类的访问特点:
      • 内部类可以直接访问外部类的成员,包括私有的
      • 外部类要访问内部类的成员,必须要去创建对象

    内部类的创建语法:

      外部类名.内部类名 对象名 = 外部类对象.内部类对象;

      注:开发中自己声明的内部类比较少用,用的较多的是集合中的遍历

    public class null01内部类 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            //创建内部类的对象
            Outer.Inner inner = new Outer().new Inner();
            inner.test1();
        }
    
        //在一个类的内部声明类,所以他是一个内部类
    //    class Student{
            
    //    }
        
    }
    //此时声明类在另一个类的外面,所以这是一个外部类
    //class Student{
        
    //}
    //这是一个外部类
    class Outer{
        int a = 12;
        private int b = 13;
        //这是一个内部类
        class Inner{
            public void test1(){
                System.out.println("内部访问外部的一个变量a:"+a);
                System.out.println("内部访问外部的私有属性b:"+b);
                
            }
        }
    }
    Java内部类的基本用法

    1.私有内部类的使用

    注:private修饰的,只能在内部访问,所以就无法使用外部类名.内部类名了

    那我们如何使用?

    和我们对私有属性的操作类似,在class类的内部声明一个获取方法

    public class null02私有内部类 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //权限修饰符:private default protected public
            //类的成员:属性,方法,内部类
            
            //创建内部类对象
            //注:private只能在内部访问,所以无法使用Outer.Inner
            //私有的内部类,就不能在外部调用了
            Insert outer = new Insert();
            outer.test();
        }
    
    }
    class Insert{
        int a = 12;
        private int b = 13;
        //这是一个内部类
        private class Inner{
            public void test1(){
                System.out.println("内部访问外部的一个变量a:"+a);
                System.out.println("内部访问外部的私有属性b:"+b);
                
            } 
        }
        public void test(){
            Inner inner = new Inner();
            inner.test1();
        }
    }
    私有内部类的实例

    2.静态内部类的使用

    创建静态内部方法对象的语句:

      注意:说道对象,那就是new出来的东西了,这个才叫对象

      外部类名.内部类名 对象名 = 外部类名.内部类对象;

    public class null03静态内部类 {
        public static void main(String[] args){
            
            //创建静态内部方法对象语法:外部类名.内部类名  对象名 = 外部类名.内部类对象;
            OuterThree.Inner inner = new OuterThree.Inner();
            inner.test1();
            
            
        }
    }
    class OuterThree{
        static int a = 12;
        static int b = 13;
        //这是一个内部类
        static class Inner{
            public void test1(){
                System.out.println("内部访问外部的一个变量a:"+a);
                System.out.println("内部访问外部的私有属性b:"+b);
                
            } 
        }
    }
    Java静态内部类

    3.调用静态内部类的静态方法

    静态内部类的静态方法调用:

      外部类.静态内部类,静态内部方法;

    public class null04调用静态类的静态方法 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            
            //调用静态内部类的静态方法
            OuterFour.Inner.test1();
        }
    
    }
    
    class OuterFour{
        static int  a = 1;
        
        //静态的内部类
        static class Inner{
            public static void test1(){
                System.out.println("这里是静态类的静态方法");
                
            }
        }
        
    }
    静态内部类的静态方法

    4.局部内部类

    • 局部内部类如果想要访问局部变量,那么局部变量必须用final修饰
      • 如果不用final修饰,在某些情况下,可能变量会先弹出,但是局部内部类还在存活
    • 局部内部类访问它所在的方法中的局部变量必须用final修饰
    • 注意:jdk1.8以上的版本不需要加final代码也不会报错了
    public class Demo01 {
        public static void main(String[] args) {
            Outer outer = new Outer();
            outer.test1();
        }
    }
    
    class Outer{
        public void test1(){
            final int a = 10;//局部变量
            class Inner{//局部内部类
                public void test2(){
                    System.out.println(a);
                }
            }
            Inner inner = new Inner();
            inner.test2();
        }
    }
    局部内部类

    5.匿名内部类

    • 抽象的或者接口的匿名内部类
      • 匿名内部类就是内部类的简化方法
      • 写匿名内部类的前提是存在一个抽象内部类或者是接口
      • 匿名内部类的实现格式:  new 抽象或者是接口名(){重写方法};
      • 匿名内部类的本质:是一个继承了该类或者实现了该接口的子类的匿名对象
      • 匿名内部类的特点:匿名内部类必须实现接口的所有方法;匿名内部类必须实现抽象类的所有方法
      • 匿名内部类的方法调用:就像是普通的对象一样,调用方法即可
    public class null05匿名内部类 {
        public static void main(String[] args){
        
            //不能直接调用抽象类
            //可以通过子类去重写抽象类
            Dog dog = new Dog();
            dog.eat();
            //可以通过匿名内部类,其实也是匿名方法
            new Animal(){
                @Override
                public void eat(){
                    System.out.println("这个是匿名内部方法");
                }
            }.eat();
            
        }
        
        
    }
    
    //写一个抽象类
    abstract class Animal{
        public abstract void eat();
    }
    class Dog extends Animal{
        @Override
        public void eat(){
            System.out.println("我是.....");
        }
    }
    抽象类的匿名内部类调用
    public class null06接口的匿名内部类 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //第一中class实现接口的调用
            DogSix dog = new DogSix();
            dog.jumpFileCircle();
        
            new AnimalSix(){
                @Override
                public void jumpFileCircle() {
                    // TODO Auto-generated method stub
                    System.out.println("annother Jump....");
                }
            }.jumpFileCircle();
            AnimalSix annther = new AnimalSix(){
                @Override
                public void jumpFileCircle(){
                    System.out.println("three jump....");
                }
            };
            annther.jumpFileCircle();
        
        
        }
    
    }
    
    interface AnimalSix{
        //跳火圈
        public void jumpFileCircle();
    }
    //之前说接口不能直接new,
    //如何使用接口、
    //1.写一个类,实现接口
    class DogSix implements AnimalSix{
        @Override
        public void jumpFileCircle(){
            System.out.println("jump...");
        }
    }
    //2.new一个接口的匿名
    接口的匿名内部类的调用

    补充一道面试题:

    package nullnull;
    
    interface Inter
    {
        void show();
    }
    class Outer{
        //补齐代码
    }
    class OutDemo{
        public static void main(String[] args){
            Outer.method().show();
        }
    }
    //在控制台输出“Helloworld”
    interface Inter
    {
        void show();
    }
    class Outer{
        //补齐代码
        public static Inter method(){
            return  new Inter(){
                @Override
                public void show(){
                    System.out.println("Helloworld");
                }
            };
        }
    }
    class OutDemo{
        public static void main(String[] args){
            Outer.method().show();
        }
    }
    面试题答案
  • 相关阅读:
    Delphi Code Editor 之 几个特性(转)
    Delphi Live Bindings 初探
    PC端和移动APP端CSS样式初始化
    移动端H5页面高清多屏适配方案
    js中的事件委托详解
    浏览器页面加载解析渲染机制
    CSS选择器渲染效率
    JS window对象的top、parent、opener含义介绍 以及防止网页被嵌入框架的代码
    关于苹果真机 getFullYear()返回值为NAN的问题
    js事件监听器用法实例详解
  • 原文地址:https://www.cnblogs.com/smiling-crying/p/9300861.html
Copyright © 2011-2022 走看看