Java入门2.1---面向对象的特征(封装性) 一、类及类的构成成分 二、面向对象的特征:封装性、继承性、多态性(抽象性)

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就会从栈中清除。
Java入门2.1---面向对象的特征(封装性)
一、类及类的构成成分
二、面向对象的特征:封装性、继承性、多态性(抽象性)

总结:关于变量的分类
1)按照数据类型的不同:基本数据类型(8种)&引用数据类型
2)按照声明的位置的不同:成员变量&局部变量
Java入门2.1---面向对象的特征(封装性)
一、类及类的构成成分
二、面向对象的特征:封装性、继承性、多态性(抽象性)

2.2 内存划分的结构:

栈(stack):局部变量、对象的引用名、数组的引用名
堆(heap):new出来的“东西”(如:对象的实体,数组的实体),含成员变量
方法区:含字符串常量、类名
静态域:声明为static的变量
Java入门2.1---面向对象的特征(封装性)
一、类及类的构成成分
二、面向对象的特征:封装性、继承性、多态性(抽象性)

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