zoukankan      html  css  js  c++  java
  • Java入门2.1---面向对象的特征(封装性)

    面向对象编程的三条主线:
    (1)类及类的构成成分:属性 方法 构造器 代码块 内部类
    (2)面向对象编程的特征:封装性 继承性 多态性(抽象性)
    (3)其他的关键字:this super package import static final abstract interface

    一、类及类的构成成分

    1.类

    基本元素:类和对象
    成员:
    (1)属性: Field=属性=成员变量:
    (2)方法:Method=(成员)方法=函数
    面向对象思想的落地法则
    (1)设计类,并设计类的成员(成员变量&成员方法)
    (2)通过类,来创建类的对象(也称作类的实例化)
    (3)通过“对象.属性”或“对象.方法”来调用,完成相应的功能
    对象之间独立
    创建的多个对象,彼此各自拥有一套类的属性,当对其中一个对象的属性进行修改时,不会影响搭配其他对象的属性值。

    2.属性(成员变量)

    2.1成员变量 VS 局部变量

    相同点:
    (1)遵循变量声明的格式:修饰符 数据类型 变量名 = 初始化值
    (2)都有作用域
    不同点:
    (1)声明的位置的不同:成员变量声明在类里,方法外;
    (2)修饰符
    成员变量的修饰符有四个:public private protected 缺省
    局部变量没有修饰符,与所在的方法修饰符相同
    (3)初始化值:一定会有初始化值
    成员变量:如果在声明时候,不显示的赋值,那么不同数据类型会有不同的默认初始化值。
    byte short int long默认值为0;
    float double默认值为0.0;
    char默认值为空格;
    boolean默认值为false;
    引用类型变量默认值为null
    局部变量:一定要显示的赋值(局部变量没有默认初始化值)
    (4)二者在内存中存放的位置不同:成员变量存在在堆空间中;局部变量存在栈空间中。
    例:局部变量n被设置为"付昊",结束调用之后n就会从栈中清除。

    总结:关于变量的分类
    1)按照数据类型的不同:基本数据类型(8种)&引用数据类型
    2)按照声明的位置的不同:成员变量&局部变量

    2.2 内存划分的结构:

    栈(stack):局部变量、对象的引用名、数组的引用名
    堆(heap):new出来的“东西”(如:对象的实体,数组的实体),含成员变量
    方法区:含字符串常量、类名
    静态域:声明为static的变量

    3.方法(提供某种功能的实现)

    3.1 格式

    权限修饰符 返回值类型(void:无返回值/具体的返回值) 方法名(形参){}

    public void eat(){}
    public String getName(){}
    public void setName(String n){}
    

    3.2 关于返回值类型

    void:表明方法不需要返回值
    有返回值的方法,在方法的最后一定有return+返回值类型对应的变量
    记忆:void与return不可以同时出现在一个方法内,像一对“冤家”
    方法内可以调用本类的其他方法或属性,但是不能在方法内再定义其他方法。

    3.3 方法的重载

    要求:
    【1】同一个类中;
    【2】方法名必须相同;
    【3】方法的参数列表不同(参数的个数不同/参数类型不同)

    方法的重载与方法的返回值类型没有关系

    class OverLoad{
        //定义两个int型变量的和
        public int getSum(int i,int j){
            return i + j;
        }
        //定义三个int型变量的和
        public int getSum(int i,int j,int k){
            return i + j + k;
        }
        
        //不能与其他几个方法构成重载
        //public void getSum(int i,int j,int k){
        //    return i + j + k;
        //}
        
        //定义两个double型数据的和
        public double getSum(double d1,double d2){
            return d1 + d2;
        }
        //定义三个double型数组的和
        public double getSum(double d1,double d2,double d3){
            return d1 + d2 + d3;
        }
    }
    
    //参数类型相同,但顺序不同是允许的
    public void method1(int i,String str){
    }
    public void method1(String str,int j){
    }
    
    //参数类型相同,但参数名字不同是不允许的
    //public void method1(int i,String str){
    //}
    //public void method1(int j,String str){
    //}
    
    //判断与void show(int a,char b,double c){}构成重载的有:
    void show(int x,char y,double z){}//no
    int show(int a,double c,char b){}//yes
    void show(int a,double c,char b){}//yes
    boolean show(int c,char b){}//yes
    void show(double c){}//yes
    double show(int x,char y,double z){}//no
    void shows(){double c;}//no
    

    3.4 匿名类对象

    创建的类的对象是匿名的。
    (1)当我们只需要一次调用类的对象时,我们就可以考虑使用匿名的方式创建类的对象。
    (栈中没有名字,堆中有类的对象)
    (2)特点:创建的匿名类的对象只能够调用一次。

    3.5 可变个数的形参的方法

    (1)格式:对于方法的形参:数据类型 ... 形参名
    (2)可变个数的形参的方法与同名的方法之间形成重载
    (3)可变个数的形参在调用时,个数从0开始,到无穷多个
    (4)使用可变多个形参的方法与方法的形参使用数组是一致的
    (5)若方法中存在可变个数的形参,那么一定要声明在方法形参的最后
    (6)在一个方法中,最多声明一个可变个数的形参

    public void sayHello(){
       System.out.println("hello world");
    }
    public void sayHello(String str1){
       System.out.println("hello " + str1);
    } 
    //可变个数的形参的方法,包含前两个方法,实际写的时候,可以省略前两个方法
    public void sayHello(String ... args){
    	for(int i=0;i<args.length;i++){
    		System.out.println(args[i]);
    	}
    }
    
    public void sayHello1(String[] args){
    	for (int i=0;i<args.length;i++){
    		System.out.println(args[i]);
    	}
    }
    
    /*
    public int getSum(int i,int j){
        return i + j;
    }
    public int getSum(int i,int j,int k){
        return i + j + k;
    }
    */
    public int getSum(int ... args){
        int sum = 0;
        for(int i = 0;i < args.length;i++){
            sum += args[i];
        }
        return sum;
    }
    

    3.6 方法的参数(值)传递(重点、难点)

    (1)形参:方法声明时,方法小括号内的参数
    实参:调用方法时,实际传入的参数的值
    (2)规则:java中的参数传递机制,值传递机制
    【1】形参是基本数据类型的:将实参的值传递给形参的基本数据类型的变量

    /*
    public class TestArgsTransfer{
        public static void main(String[] args){
            TestArgsTransfer tt = new TestArgsTransfer();
            DataSwap ds = new DataSwap();
    
            System.out.println("ds.i "+ds.i+" ds.j "+ds.j);
    
            tt.swap(ds);
            System.out.println("ds.i "+ds.i+" ds.j "+ds.j);
        }
    
        public void swap(DataSwap d){
            int tmp = d.i;
            d.i = d.j;
            d.j = tmp;
        }
    }
    
    class DataSwap{
        int i = 10;
        int j = 5;
    }*/
    
    public class TestArgsTransfer{
        public static void main(String[] args){
            int i = 3;
            int j = 6;
            TestArgsTransfer tt = new TestArgsTransfer();
            System.out.println("i "+i+" j "+j);
    
            tt.swap(i,j);
            System.out.println("i "+i+" j "+j);//没有交换
        }
    
        public void swap(int i,int j){
            int tmp = i;
            i = j;
            j = tmp;
        }
    }
    

    【2】形参是引用数据类型的:将实参的引用类型变量的值(对应的堆空间的对象实体的首地址)传递给形参的引用类型变量

    public class TestArgsTransfer{
        public static void main(String[] args){
            TestArgsTransfer tt = new TestArgsTransfer();
            DataSwap ds = new DataSwap();
    
            System.out.println("ds.i "+ds.i+" ds.j "+ds.j);
    
            tt.swap(ds);
            System.out.println("ds.i "+ds.i+" ds.j "+ds.j);
        }
    
        public void swap(DataSwap d){
            int tmp = d.i;
            d.i = d.j;
            d.j = tmp;
        }
    }
    
    class DataSwap{
        int i = 10;
        int j = 5;
    }
    

    举例:

    class Value{
        int i = 15;
    }
    class Test{
        public static void main(String argv[]){
            Test t = new Test();
            t.first();
        }
    
        public void first(){
            int i = 5;
            Value v = new Value();
            v.i = 25;
            second(v,i);
            System.out.println(v.i);
        }
    
        public void second(Value v,int i){
            i = 0;
            v.i = 20;
            Value val = new Value();
            v = val;
            System.out.println(v.i + " " + i);
        }
    }
    

    最终结果为:

    15 0
    20
    

    4.构造器(构造方法)

    类的第三个成员:构造器(constructor 构造方法)
    constructor:建造者
    构造器的作用:(1)创建对象;(2)给创建的对象的属性赋值
    【1】设计类时,若不显示声明类的构造器的话,程序会默认提供一个空参的构造器
    【2】一旦显示的定义类的构造器,那么默认的构造器就不再提供
    【3】如何声明类的构造器,格式:权限修饰符 类名(形参){}
    【4】类的多个构造器之间构成重载

    public class TestPerson{
        public static void main(String[] args) {
            Person p1 = new Person();
            String str = new String("bunny");
            Person p2 = new Person("aa");
        }
    }
    
    class Person{
        //属性
        private String name;
        private int age;
    
        //构造器
        public Person(String n){
            name = n;
        }
    
        public Person(){
    
        }
    
        public Person(int a){
            age = a;
        }
    
        public Person(String n,int a){
            name = n;
            age = a;
        }
    }
    

    类对象的属性赋值的先后顺序:
    (1)属性的默认初始化(new数据类型的默认值);
    (2)属性的显示初始化(定义数据类型时候的赋值);
    (3)通过构造器给属性初始化;(对象.setName());
    (4)通过”对象.方法“的方式给属性赋值

    二、面向对象的特征:封装性、继承性、多态性(抽象性)

    1.封装与隐藏

    当创建了类的对象以后,如果直接跳过“对象.属性”的方式对相应的对象属性赋值的话,可能会出现不满足实际情况的意外,我们考虑不让对象来直接作用属性,而是通过“对象.方法”的形式,来控制对象对属性的访问。实际情况中,对属性的要求就可以通过方法来实现。
    private修饰的属性,只能在本类中被调用,出了此类,就不能被调用了。
    解决方法:
    【1】(封装性的思想)将类的属性私有化;
    【2】提供公共的方法来调用,setter设置,getter获取
    举例:

    public class TestArgsTransfer{
        public static void main(String[] args) {
            Animal a1 = new Animal();
    //        a1.name = "芙芙";
    //        a1.legs = 2;
        }
    }
    
    class Animal{
        //private修饰的属性,只能在本类中被调用,出了此类,就不能被调用了。
        private String name;//动物的名字
        private int legs;//腿的个数
    
        public void eat(){
            System.out.println("动物进食");
        }
    
        public void sleep(){
            System.out.println("动物睡觉");
        }
    
        public void info(){
            System.out.println("name:"+name+"legs:"+legs);
        }
    
        //获取类的属性
        public int getLegs() {
            return legs;
        }
    
        public String getName() {
            return name;
        }
    
        //设置类的属性
        public void setLegs(int l) {
            if(l > 0 && l % 2 == 0){
                legs = l;
            }else{
                System.out.println("您输入的数据有误");
            }
        }
    
        public void setName(String n) {
            //...
            name = n;
        }
    }
    

    权限修饰符:public private 缺省 protect
    4个都可以用来修饰属性、方法;
    注:
    1)权限从大到小排列,public > protected > 缺省 > privated
    2)修饰类的权限有:public、default(缺省)

    2.this

    this的使用方法:

    1. this可以用来修饰属性、方法、构造器
    2. this理解为当前对象或当前正在创建的对象。比如:this.name,this.show()
    3. 可以在构造器中通过“this(形参)”的方式显示本类中其他重载的指定的构造器,要求:
    4. 在构造器内部必须声明在首行;
      this的使用场景:
    5. 当形参与成员变量重名时候,如果在方法内部需要使用成员变量,必须添加this来表明该变量是类成员;
    6. 在任意方法内,如果使用当前类的成员变量或成员方法,可以在其前面添加this,增强程序的阅读性。
    7. 在构造器中使用“this(形参列表)”显示的调用本类中重载的其他的构造器
      要求“this(形参列表)”要声明在构造器的首行!
      若一个类中有n个构造器,那么最多有n-1个构造器中使用了this(形参)。
      举例:
    public class TestPerson{
    public static void main(String[] args) {
    Person p = new Person();
    p.setAge(10);
    p.info();
    p.setName("牛");
    p.info();
    System.out.println();
    
    Person p1 = new Person("韩梅梅",23);
    p1.info();
    
    Person p2 = new Person(23);
    p2.info();
    }
    }
    
    class Person{
    //属性
    private String name;
    private int age;
    
    //构造器
    public Person(String name){
    this.name = name;
    }
    
    public Person(){
    age = 12;
    }
    
    public Person(int age){
    this.age = age;
    }
    
    public Person(String name, int age){
    this(name);
    this.age= age;
    }
    
    //this.name表示当前正在创建的对象
    //name是形参
    public Person(String name,int age){
    //this.name = name;
    this(name);//可以用来显示的调用当前类的重载的指定的构造器
    System.out.println("这里是person类中形参为name和age的构造器");
    this.age = age;
    }
    //this.name表示当前对象的属性
    //name是形参
    public void setName(String name){
    this.name = name;
    }
    
    public void setAge(int age) {
    this.age = age;
    }
    
    public String getName() {
    return name;
    }
    
    public int getAge() {
    return age;
    }
    
    public void eat(){
    System.out.println("人吃饭");
    }
    
    public void sleep(){
    System.out.println("人睡觉");
    }
    
    public void info(){
    System.out.println("name:"+this.name+"age:"+this.age);
    this.show();
    }
    
    public void show(){
    System.out.println("show方法:"+this.name);
    }
    }
    
    name:nullage:10
    show方法:null
    name:牛age:10
    show方法:牛
    
    这里是person类中形参为name和age的构造器
    name:韩梅梅age:23
    show方法:韩梅梅
    name:nullage:23
    show方法:null
    

    3.JavaBean

    JavaBean是一种Java语言写成的可重用组件。

    所谓JavaBean,是指符合如下标准的Java类:

    • 类是公共的;
    • 有一个无参的公共的构造器;
    • 有属性,且有对应的get、set方法。

    4.package

    声明源文件所在的包,写在程序的第一行。
    每“.”一次,表示一层文件目录。

    5.import

    显示导入指定包下的类或接口;
    写在包的声明和源文件之间;
    如果需要引入多个类或接口,那么就并列写出;
    如果导入的类是java.lang包下的,如:System String Math等,就不需要显示的声明。
    理解.的概念,比如java.util.
    如何处理同名类的导入,如:在util包和sql包下同时存在Date类;
    import static 表示导入指定类的static的属性或方法。
    导入java.lang.*只能导入lang包下的所有类或接口,不能导入lang的子包下的类或接口。

    package、import

  • 相关阅读:
    常见限流算法
    spring aop 事物
    Java序列化和反序列化为什么要实现Serializable接口
    java类在何时被加载?
    mysql 排序 是怎么工作的?
    程序员转正述职报告
    .NET中使用Channel<T>
    .NET-服务承载系统(Hosting)(支持Cron表达式)
    JObject拼接Json字符串
    NET5 使用FTP发布
  • 原文地址:https://www.cnblogs.com/nxf-rabbit75/p/11100174.html
Copyright © 2011-2022 走看看