【Java】基础复习06_面向对象编程

面向过程编程

 

面向对象编程

本质:以类的方式组织代码,以对象的形式组织数据

特征:封装、继承、多态

二、类和对象的关系

类:抽象的数据类型,是对事物整体的描述,并不能代表某一个具体的事物

对象:是抽象概念的具体实例(人-->张三,狗-->旺财)

创建与初始化对象

使用new关键字创建对象,除了分配内存空间以外,还会给创建好的对象进行默认的初始化以及对类中构造器(构造方法)的调用,new关键字本质就是在调用构造器

类名 对象名//创建对象

对象名=new 类名(); //实例化对象

类名 对项名 =new 类名();//二合一

同一个包内可以直接调用

练习 创建一个person类,属性为name,age,gander

public  class  Person{

string name;

int age;

char gender;

}

public class Test{

Person per1=new Person();

Person per2=new Person();

Person per3=new Person();

per1.name="张三";

per2.age=20;

per3.gender="男";

sysout(pri1.name);

}

成员变量

实例变量:变量是属于对象的

声明实例变量

[修饰符] 数据类型 变量名=[值]

如果在声明的时候赋值了,就相当于在实例化对象的时候,该成员变量的默认值,后期可改

int id;

String name="张三";

使用实例变量

前提:必须得有对象

访问方式:对象名.成员变量名;

成员变量是有初始值的(默认值)

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

1.位置:成员变量在类里;局部变量在某个局部(方法里,循环里)

2.作用范围:本类及其他类可以调用(符合访问修饰符);局部变量当前方法作用域

3.初始化值:成员变量有初始化值;局部变量没有初始化值

4.内存中的位置:成员变量在堆中;局部变量在栈中

5.生命周期:成员变量是在对象被回收的时候销毁;局部变量是当大括号运行完毕就销毁。

成员变量的类型可以是任意类型(可以基本数据类型,可以是引用数据类型(String,数组,自定义类))

练习 创建一个Employee类,内有属性(id/name/salary/phone);创建Employee对象,为对象所有的属性赋值,并展示该员工所有信息

public class Employee{

int id;

String name;

double salary;

Phone phone;//引用数据类型,自定义的类

}

public class Phone{

String name;

String brand;

int size;

}

Public class Test{

        public static void mian(String [] args){

                Employee emp= new Employee();

                emp.id=11;

                emp.name="张三";

                emp.salary=123;

                Phone phone=new Phone ();

                phone.name="P30pro"

                phone.brand="华为";//员工手机的品牌;phone.brand是手机的品牌

                emp.phone=phone;//将phone这部手机设置是emp的,不然就空指针异常了

                sysout(emp.name+"的手机品牌是"+emp.phone.brand);

        }

}

类变量:变量属于类(待补充)

成员方法

1.先声明后使用(在本类内可以直接调用,在本类以外需要先创建对象才能调用)

2.调用一次执行一次,不调用不执行,调用一次压入一次方法栈

分类:实例方法(属于对象的,必须有对象才可以)、类方法(待补充)

语法:[修饰符] 返回值类型 方法名([形式参数]){方法体}

实例方法分类:无参无返回值、有参无返回值(可以是任意类型,基本数据类型,引用数据类型)、无参有返回值(返回值类型任意,但要指定只能指定一个;只能有一个返回值,有返回值的方法必须要执行到return)、有参有返回值

如果要是有返回值的,方法里一定要检测到有返回值的才能结束。

//面向过程,//打印5次好好学习天天向上

public class Test{

        public static void main (String [] args){

                for(int i=0;i<5;i++){

                        sysout("好好学习,天天向上");

                }
        }

}

//面向对象,//无参无返回值   //打印5次好好学习天天向上

public class Test{

        public static void main (String [] args){

             MyUtil myUtil =new MyUtil();

                myUtil.print();
        }

}

//创建一个人去做这件事,创建MyUtil类,里面写print方法,以后就可以重复使用了

public class MyUtil{

        public void print(){         //无参无返回值

                for(int i=0;i<5;i++){

                        sysout("好好学习,天天向上");

                }

        }

}

//有参无返回值,创建n行直角三角形

public class Test{

        public static void main (String [] args){

             MyUtil myUtil =new MyUtil();

                myUtil.printNum(5);//需要传参
        }

}

public class MyUtil{

        public void printNum( int num){//执行的时候一定有值

                for(int i=0 ;i<num;i++){

                        for (int j=0;j<=i;j++){

                                sysout("*");

                        }

                }

        }

}

//有参无返回值练习     //遍历int数组 ,并把数组从小到大排序

public class Test{

        public static void main (String [] args){

         int [] arr= new int{3,4,8,5,7,8};

             MyUtil myUtil =new MyUtil();

                myUtil.printNum(arr);//需要传参//遍历int数组

                myUtil.sort(arr);//从小到大排序(冒泡)
        }

}

public class MyUtil{

        public void printNum( int [] arrs){//执行的时候一定有值

                for(int i=0 ;i<arrs.length;i++){    //遍历int数组

                        sysout(arrs[i]);
                }

        }

        public void sort(int [] arrs){

                        //从小到大排序(冒泡)

                    for(int i=0;i<arrs.length;i++){

                        for(int j=0;j<arrs.length-i-1;j++){

                                if(arrs[j]>arrs[j+1]){

                                        int temp=arrs[j];

                                        arrs[j]=arrs[j+1];

                                        arrs[j+1]=temp;

                                }

                        }

                }

        }

}

//无参有返回值

//[public] 返回值类型 方法名(){}

//随机产生一个四位数字

public class Test{

        public static void main (String [] args){

             MyUtil myUtil =new MyUtil();

                int a=myUtil.randomNum();//把myUtil.randomNum()的返回值赋给同类型的变量

                sysout(a);
        }

}

public class MyUtil{

        public int randomNum( ){

                int num =(int)(math.random()*9000+1000);

                return num; //返回int型num。如果想返回多个值,类型相同的可用数组;不同的话可以使用集合(后面写)。有返回值的方法必须要执行到return。

        }

}

练习随机返回n个随机数

public class MyUtil{

        public int random5Num( ){

                int [] arrs=new int[3];

                for(int i=0;i<3;i++){

                         arrs[i]=(int)(math.random()*9000+1000);

                }

                return arrs; //返回数组。

        }

}

public class Test{

        public static void main (String [] args){

             MyUtil myUtil =new MyUtil();

                int []a=myUtil.random5Num();

                sysout(a);
        }

}

//有参有返回值 随机返回n个

public class MyUtil{

        public int randomnNum( ){

                int [] arrs=new int[n];

                for(int i=0;i<n;i++){

                         arrs[i]=(int)(math.random()*9000+1000);

                }

                return arrs; //返回数组。

        }

}

public class Test{

        public static void main (String [] args){

             MyUtil myUtil =new MyUtil();

                int count=7;

                int []a=myUtil.randomnNum(count);//有参

                for(int i=0;i<a.length;i++){

                        sysout(a);//有返回值

                }
        }

}

练习

public class test{

        public static void main (String [] args){

                MyTools myTools =new MyTools();

                double max3 =myTools.max3(23.5,60,7);

                double max1 =myTools.max1(20,7);

         }

}

public class MyTools{

        public double max1(double a,double b){

                return a>b? a:b;

        }

        public double max3(double a,double b,double c){

                double max=max1(a,b); //调用类内方法可以直接调用不需要创建对象

                return max>c?max:c;

        }

}

方法入栈:先进后出

方法调用用一次执行一次,调用一次就入栈一次

入栈:在栈内存中分配一块空间供当前这个方法运行使用,方法结束就销毁出栈,再调用时再入栈。

方法重载

解决相同类型方法,起名问题

同一类中方法名可以相同,但是形参列表必须不同(顺序/个数/类型)

和返回值无关,和修饰符也无关

参数传递机制

引用数据类型:栈内存存储的是地址,在方法传参的时候,就是地址传递(引用)--。多个变量指向同一个空间(堆内存,常量池)

基本数据类型:栈内存中存储的是值,在方法传参的时候,就是值传递

递归

直接递归:方法自己调用自己(容易内存溢出)、间接递归:a->b->c->a

public class test {

        public static void main(String [] args){

                Function b= new Function();

                b.function(0);

        } 

}

public class Function{

        public void funcion(int a){

                if (a<3){

                        sysout("好好学习天天向上");

                        a++;

                        function(a);

                }

        }

}

/**

构造方法:创建对象时候必须要调用的,一个类什么都不写也会存在一个无参构造方法。

  • 与类名相同
  • 必须没有返回值,也不是void

作用:

  • new本质就是在调用构造器
  • 初始化对象的值

注意:

  • 如果定义了有参构造方法,无参构造必须显式定义
  • 快捷键Alt+Insert(IDEA)

public class Person{

String name;

//一旦有有参构造方法,无参构造必须显式定义

public Person(){//无参构造

}

public Person(String name){//有参构造

this.name=name;//this.name 是类里的变量,name是传进来的参数

}

}

引用类型

对象是通过引用来调用的,栈---->堆

**/

三、三大特性

封装

该露的露,该藏的藏,高内聚(类内部数据操作细节自己完成,不许外部干涉)低耦合(尽量暴露少量的方法给外部使用),通过接口方法来操作

属性私有,get/set方法、可设置元素:类,成员变量,成员方法

权限(访问)修饰符:public、缺省的、protected、private

范围:

本类内本包内其他包的子类其他包的非子类
public
protected×
缺省的××
private×××

作用:提高安全性,隐藏代码实现细节,统一接口,系统的可维护性

...

public int getId(){//public方法

}

public void setId(int id){

this.id=id;

}

class Demo1{//缺省的类

}

protected class Demo2{//protected类

}

public void test(){

        private int a;//private成员变量

}

...

练习

//创建一个employee类,工友属性id age name salary,对所有属性进行私有化,每个属性都要提供对应的get/set方法,并且提供setAll和getInfo

//创建共三个对象,存放在对象数组中,循环遍历其个人信息

public class Employee {

        private int id;

        private int age;

        private String name;

        private double salary;

//set方法

        public void setId(int a){

        id =a;

        }

        public void setAge(int b){

        age =b;

        }

        public void setName(String c){

        name =c;

        }

        public void setAll(int a,int b,String c,double d){

                id=a;

                age =b;

                name =c;

                salary=d;

        }

//get方法

        public int getId(){

                return id;

        }

        public int getAge(){

                return age;

        }

        public String getName(){

                return name;

        }

        public String getInfo(){

                return id+"\t"+name+"\t"+age+"\t"+salary;

        }

}

public class Test{

        public static void main(String [] args){

                Employee [] employees =new Employee[3];//创建一个对象,放长度为三的数组

                employees [0]=new Employee();//创建这个数组的第一行

                employees [0].setId(11111);

                employees [0].setAge(12);

                employees [0].setName("刘欢");

                employees [1]=new Employee();

                employees [1].setId(11112);

                employees [1].setAge(25);

                employees [1].setName("法外狂徒");

                employees [2]=new Employee();

                employees [2]. setAll(11113,57,"老王",3355.3);

                for(int i=0;i<employees.length;i++){

                       sysout(employees.getInfo());

                }

        }

练习

//基于文本界面的用户登录注册

public class Test{

        public static void main(String []args){

        java.util.Scanner input=new java.util.Scanner(System.in);

        int num =input.nextInt();

        int count=0;//记录用户个数

        User [] users=new User[5];//保存用户的数组

        if(num==1){

                sysout("欢迎来到注册页面\n请输入用户名和密码");

                 int username=input.nextInt();

                 int password=input.nextInt();

                sysout("请输入您的真实姓名:");

                String name=input.next();

                //用户信息的保存(对象数组)将注册用户信息,封装到对象内,将对象存在数组中

               //1.判断容量是否充足

                if(count==users.length){

                //需要扩充

                User[] newUser=new User[user.length*2];

                for(int i=0;i<users.lenth;i++){

                                newUser[i]=users[i];

                        }

                   users=newUser;

                }

                //2.保存用户

                User.user=new User();//把用户数据封装成用户对象,再把用户对象放到数组里

                user.setId(count);

                user.setUsername(username);

                user.setPassword(password);

                user.setName(name);

                users[count++]=user;//把用户对象放到数组里

                  }else if(num==2){

                         sysout("欢迎来到登录页面\n请输入用户名和密码");

                         int username=input.nextInt();

                         int password=input.nextInt();

                         //登录检查

                        for(int i=0;i<count;i++){

                                if(username==users[i].getUsername()&&password==users[i].getPassword){

//找到登录人

user=users[i];

break;

if(){user==null;

sysout("用户名密码错误");

}

                                }

                        }

                }else if(num==3){

                        sysout("确认退出吗?0/1");

                        int flg=input.nextInt();

                        if(flg==0){

                        break;

                        }

                }

        }

}

//user类

public class User(){

        private int id;

        private int username;

        private int password;

        private String name;

        public void setId(int i){

                id =i;

        }

        public int getId(){

                return id;

        }

        public void setUsername(int u){

                username =u;

        }

        public int getUsername(){

                return username;

        }

        public void setPassword(int p){

                password=p;

        }

        public int getPassword(){

                return password;

        }

        public void setName(int n){

                name=n;

        }

        public int getName(){

                return name;

        }

}

构造器

是类的五大成员之第三大成员

成员变量、成员方法、构造器、初始化块、内部类

构建对象的(实例化对象的)又称为构造方法(和方法类似)

2.构造器语法

方法:修饰符 返回值类型 方法名(形参列表){代码块}

构造器:没有返回值(void也没有)、方法名必须和类名一致、创建对象时候必须要调用的,一个类什么都不写也会存在一个无参构造方法,如果写了就会覆盖。

public class Person{

        public person(){//没有返回值(void也没有)、方法名必须和类名一致

                sysout("无参构造");

        }

}

public class Test{

        public static void main (String [] args){

                Person person =new Person();

        }

}

//构造器也可以重载

public class Person{

        public person(){//没有返回值(void也没有)、方法名必须和类名一致

                sysout("无参构造");

        public person(String n){//有参构造器、构造器可以重载、但如果写了就会覆盖默认构造器

                sysout("有参构造");

        }

}

public class Test{

        public static void main (String [] args){

                Person person =new Person();

        }

}

3.构造器的执行时机

在实例化对象的时候调用,实例化一次调用一次

构造器只能在new的时候调用,后续对象名打点调用不了

4.构造器和set方法

有参构造器:在实例化对象的时候就已经知道属性的时候使用

set:单个属性值的修改

5.封装类必备三要素:1私有属性、2公有get/set方法、3共有的无参构造器

一般情况:1私有属性、2公有get/set方法、3全参构造器(所有属性值的初始化)、4显示的创建无参构造器、5getInfo()方法--->toString

public class Student{

        private int id;//1私有属性

        private String name;//1私有属性

        public Student(int i,String n){//3全参构造器(所有属性值的初始化)

                id =i;

                name=n;

        }

        public Student(){//4显示的创建无参构造器

        }

        public int setId(int i){//2公有set方法

                id=i;

        }

        public int getId(){//2公有get方法

                return id;

        }

        public String setName(String name){//2公有set方法

                this.name=name;

        }

        public String getName(){//2公有get方法

                return name;

        }

        public String getInfo(){//5getInfo()方法--->toString

                return id+"\t"+name;//\t”为“转义字符“,代表的是一个tab,也就是8个空格

        }

}

Java中无参构造器的作用是什么?(就像你给的代码中的Student默认构造函数,可以在里面执行一些默认的代码或操作。这样用户在初始化这个类时,可以默认执行一些操作。比如环境准备,默认数据填充等。这样用户拿到类的对象时,就已经有一些默认数据了。)

/**声明一个员工类,包含属性:编号、姓名、薪资、性别,要求属性私有化

提供无参构造器和有参构造器

提供getInfo方法**/

public class Employee{

//属性私有化
    private int id;
    private String name;
    private double salary;
    private char gender;

//提供无参构造器
    public employee(){

    }
//提供有参构造器
    public employee(int i,String n,double sa,char g){
        id=i;
        name=n;
        salary=sa;
        gender=g;

    }
//get、set方法
    public void setId(int i){
        id=i;
    }

    public int getId(){
        return id;
    }
//......

//提供getInfo方法
    public String getInfo(){
        ruturn id+"\t"+name+"\t"+salary+"\t"+gender;
    }

}


//测试类
public class Test{

    public static void main(String [] args){
       // Employee[] employee =new Employee[3];
       // employee[0]=new Employee();
       // employee[0].id=11111;
       // employee[0].name="张三丰";

          Employee employee =new Employee();
    //使用无参构造器,用set方法设置值
           employee.setId(11111); 
           employee.setName("张三丰");
           //......
            sysout(employee.getInfo());

    //使用有参构造器,在new的时候直接给初始化值
           Employee employee2 =new Employee(11112,"张无忌",500,'男');
           sysout(employee2.getInfo());
        
    }
}

this关键字:当前对象(不是当前类)

作用1:this.内容(属性、方法)

可以用在所有方法(包括构造器)

public class Car{
    private int id=20;//这是个成员变量,在创建对象的时候就初始化值了
    private String name;

    //get、set方法
    public void setId(){
       id=10;//这是个局部变量。//同一个作用域内不允许重名的变量,但是成员变量和局部变量重名
       sysout(id);//这时候运行的的结果id=10,因为有局部变量的时候默认访问局部变量

       sysout(this.id)//要是想访问成员变量id,就用this.属性名,this是当前对象,谁调的setId就是谁这里是car调的
    }


}

//测试类
public class Test{
    public static void main(String [] args){
        Car car =new Car;
        car.setId();
    }

}

同一个作用域内不允许重名的变量,但是成员变量和局部变量重名
局部变量和成员变量重名的情况下,候默认访问局部变量

要是想访问成员变量id,就用this.属性名,this是当前对象,谁调的setId就是谁,这里是car调的

作用2:应用在构造器、调用本类的其他构造器

注意:this()必须在构造器的首行

public class Car{
    private int id=20;//这是个成员变量,在创建对象的时候就初始化值了
    private String name;

    //get、set方法
    public void setId(){
       id=10;//这是个局部变量。//同一个作用域内不允许重名的变量,但是成员变量和局部变量重名
       sysout(id);//这时候运行的的结果id=10,因为有局部变量的时候默认访问局部变量

       sysout(this.id)//要是想访问成员变量id,就用this.属性名,this是当前对象,谁调的setId就是谁这里是car调的
    }
//2个参数的构造器
    public Car(int id,String name){
        this.id=id;
        this.name=name;
    }
}

//一个参数的构造器
    public Car(String name){
        this.name=name;
    }



//有多个构造器,可以参数多的在本类中调用参数少的构造器

    public Car(int id,String name){

        this(name);//调用一个参数的构造器了,this()必须在构造器的首行
        this.id=id;
        
    }

//无参构造器
     public Car(){}

}

//测试类
public class Test{
    public static void main(String [] args){
        Car car =new Car;
        car.setId();
    }

}

Alt + Insert:代码自动生成,如生成对象的 set / get 方法,构造函数,toString() 等

标准Javabean(实体类

类必须是具体的和公共的,并且具有无参数的构造方法,成员变量私有化,并且提供用用来操作成员变量的set和get方法。(其实就是封装类的必备三要素)

语法:全小写,用.来分割级别

作用:

1.避免类的冲突(有必要创建两个同名类)、

2.分门别类的管理(Java.lang包含Java的核心类、Java.net、java.io、java.sql、java.util ...)

使用方式:使用其他包下的内容时,要先导包 import java.uli;.Scanner(Java.lang包除外)

                  使用同包下的内容不需要导包

3.可以控制某些类型成员的可见范围(访问修饰符 缺省的只能访问本包内,其他包访问不了)

static修饰成员变量(静态的)        

成员变量:属于对象

类变量:属于类,在成员变量添加修饰符static

👇实例变量例子

public class Test{
    public static void main (String [] args){
        Phone phone1 =new Phone(1,"华为",5000);//直接调用构造器赋值
        Phone phone2 =new Phone(2,"小米",3000)

        sysout(phone1.getInfo);
        sysout(phone2.getInfo);
    }

}

public class Phone{

    private int id;
    private String name;
    private double price;

//get,set方法
    public int setId(int id){
        this.id=id;
    }
//...

//有参构造器
    public phone(int id,String name, double price){
        this.id=id;
        this.name=name;
        this.price=price;
    }


//无参构造器
    public phone(){
        
    }

//getInfo获取信息
    public String getInfo(){
        return id+\t+name+\t+price
    }



}

 类的加载时机:

在第一次使用这个类的时候,先加载后使用(在使用main方法之前就先调用了Test类)

类只加载一次,在没有被销毁(垃圾回收)之前都不会再加载(在方法区每个类只有一个加载信息)

👇类变量例子

类变量:在成员变量前加static

    private int id;
    private String name;
    private static double price;//其他代码和上面一样,只改这行

//结果

1 华为 3000//空间开辟再方法区内,并且只有一份,所以是共享的

2 小米 3000

类在加载的时候:先加载所有的静态资源、再加载所有普通资源

静态的属性,空间开辟再方法区内,并且只有一份,原因类只加载一次,所有对象操作该属性的时候,操作的都是方法去这一个空间,达到共享的目的。(math.pi派

用法:1.对象.静态属性(符合权限修饰符的范围)

private static double price--->static double price

phone1.price=5000;

2.类名.静态属性(符合权限修饰符的范围)推荐

Phone.price=5000;

static修饰成员方法

实例方法:属于对象

类方法:属于类

public class Test{
    public static void main (String [] args){
        Phone phone1 =new Phone(1,"华为",5000);//直接调用构造器赋值
        Phone phone2 =new Phone(2,"小米",3000)

        sysout(phone1.getInfo);
        sysout(phone2.getInfo);
    }

}

public class Phone{

    private int id;
    private String name;
    private double price;

//get,set方法
    public int setId(int id){
        this.id=id;
    }
//...
//普通方法
    public void method(){
        sysout("这是一个普通方法");
    }

//静态方法
    public static void function(){
        sysout("静态方法");
    }

//有参构造器
    public phone(int id,String name, double price){
        this.id=id;
        this.name=name;
        this.price=price;
    }


//getInfo获取信息
    public String getInfo(){
        return id+\t+name+\t+price
    }



}

 在加载的时候,依然是先加载静态方法,再加载普通方法

使用方法:

1.对象.静态方法();

phone1.funcion();

2.类名.静态方法();推荐,不依赖与对象,工具类的方法设置为static

Phone.funcion();

注意:静态资源内只能直接使用静态资源,不能直接使用非静态资源(因为类加载的时候还没出来),因为静态资源里没有this

非静态资源内部可以直接使用this关键字

static用途:用于属性、为了资源共享;用于方法、为了类名调用方便。

9.静态导入

import static java.lang.Math.PI;

...

sysout(PI)

10.一些工具类介绍

10.1Arrays数组工具类

java.unil.Array:提供了很多静态方法对数组进行操作,而且如下每一个方法都有各种重载形式

copyOf() 数组的拷贝--用于数组扩容

public class Test{
    public static void main (){
        int[] arrs={3,4,6};

///被代替代码段//
        int[] newArrs=new int[arrs.length];
        for(int i=0;i<arrs.length;i++){
            newArrs[i]=arrs[i];
        }
//array工具类方法代替上面代码//

        int[] ints = Arrays.copyOf(arrs(被复制的数组名),arrs.length(新数组需要的长度));//有很多种类,因为方法重载


    }


}

sort() 数组排序,默认从小到大

public class Test{
    public static void main (){
        int[] arrs={3,4,6,1,2,5,3,8};
        Arrays.sort(arrs);//默认从小到大排序

        for(int i=0;i<arrs.length;i++){
            sysout(arrs[i]);
        }
    }
}

toString() 将数组内容拼接成字符串

public class Test{
    public static void main (){
       String[] strs={"北京","朝阳区","群众"};
       sysout(Arrays.toString(strs));
    }
}

结果:["北京","朝阳区","群众"]

10.2.系统类system

系统类中有很多好用的方法,常用的两个

static long currentTimeMills();返回当前系统的时间距离1970-1-1 0,0:0的毫秒值

System.exit(status 0);//系统退出

public class Test{
    public static void main(String [] args){
        sysout(System.currentTimeMills());//返回当前系统的时间距离1970-1-1 0,0:0的毫秒值
        System.exit(status 0);//系统退出,一般不用
    }
}

static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length);从指定数组中复制一个数组,复制从指定的位置开始,到目标的位置结束。

10.3数学类Math

random() //产生[0-1)随机数

abs(int) //绝对值

ceil(double) //向上取整(比参数大的最近的整数)

floor(double) //向下取整(比参数小的最近的整数)

round(double) //四舍五入

pow(int a,int b) //返回a的b次方

sqrt(double a) //开根号

PI //返回圆周率

max(double a,double b); //返回ab中最大的

min(double a,double b); //返回ab中最小的

public class Test{
    public static void main(String [] args){
        sysout(Math.abs(-5));//返回绝对值--》5
        sysout(Math.ceil(23.1));//向上取整--》24.0
        sysout(Math.floor(23.1));//向下取整--》23.0
        sysout(Math.pow(2,3));//返回2的3次方--》8
        sysout(Math.sqrt(4));//开4平方--》2
    }
}

11.API

只要是Java提供的类,在API里都能查到(上面的工具类都能查到,很全)

继承

1.1继承的好处:提高复用性

1.2.语法:class Sub extends Super{}

1.3使用时机:多个类中有相同内容;在写子类时候发现可有父类可继承

是对某一批类的抽象,关键字extends,Java只有单继承

在Java中所有的类都默认直接或间接继承Object类(String是继承于Object类的)

Ctrl+H 继承树快捷键

public class Person(){

... ...

}

public class Student extends Person(){

... ...

}

2.继承之成员变量

父类中所有的成员变量都会被子类继承,但如果父类中的成员变量是私有的,子类继承了但不能直接访问,可通过继承的公有方法进行访问。

//父类中所有的成员变量都会被子类继承,但如果父类中的成员变量是私有的,子类继承了但不能直接访问

/*
*父类Animal
*/
public class Animal{

//属性
    public Stirng name="旺财";
    int age;
    public String color;

//一些普通方法
    public void eat(){
        sysout(name+"在吃饭");
    }
    public void run(){
        sysout(name+"在奔跑");
    }

//方法:get、set、有参构造、无参构造
    public String setName(String name){
        this.name=name;
    }
    public String getName(){
        return name;
    }
//...其他get、set方法...
//有参构造
    public Animal(String name,int age,String color){
        this.name=name;
        this.age=age;
        this.color=color;
    }
//无参构造
    public Animal(){
        
    }
    
}


/*
*子类Dog继承父类Animal
*/
public class Dog extends Animal{
    public Stirng name="二哈";//子类和父类中可以出现相同的属性名称,如果有重名属性默认访问子类属性,如果向访问父类属性要使用关键字super
    
    public void careTaker(){
        sysout(name+"在守护家园");//name是this.name,这个不重名指的就是父类,重名指的就是子类
        sysout(super.name+"在守护家园");//重名情况下访问父类属性用super关键字
    }
}

类加载时,如果有父类先加载父类再加载子类

 this是从本身开始找,本身没有找父亲,父亲没有找爷爷,爷爷没有找祖宗

super是从父亲开始找,父亲没有找爷爷,爷爷没有找祖宗

super调用不到爷爷的属性,前提是父亲存在重名属性,如果父亲不存在能调用到的

super:爹的东西,this:儿子的东西(变量、方法)

public class Person(){

protected String name="hahahha";

}

--------------------------------------------------------------------

public class Student extends Person(){

protected String name="aaaaa";

public void test(String name){

sysout(name);

sysout(this.name);

sysout(super.name);

}

}

---------------------------------------------------------------------

public class A(){

Student  student =new Student() ;

student .test(lelelelel);

}

------------------------------------------------------------------------

sysout(name);//lelelelel

sysout(this.name);//aaaaa

sysout(super.name);//hahahha

注意:

  • 私有无法被继承
  • super调用父类的构造方法,必须在构造方法的第一个
  • super必须只能出现在子类的方法或者构造方法中
  • super和this不能同时调用构造方法,不写就是默认调用父类构造器

this 与super的比较

  1. 代表的对象不同:this 本身调用这个对象,super代表父类对象的英语
  2. 前提:this:没继承也能用,super:只能在继承的条件下使用
  3. 构造方法:this():本类的构造方法,super():父类的构造方法

3.继承之成员方法

1)成员方法不重复(方法名或参数不同),访问成员方法没有任何影响

2)成员方法重复(方法名和参数都相同)--->方法重写(覆盖)

方法的重写:对父类的方法进行升级

本类内:通过super去调用父类的重复方法

其他类:没有直接的办法调用到父类方法

静态方法是类的方法,非静态的是对象的方法。

静态(没有重写),方法的调用只和左边,定义的数据类型有关

public class B(){

public static void test(){

sysout("B");

}

}

----------------------------------------------------

public class Bextends B(){

public static void test(){

sysout("A");

}

}

----------------------------------------------------

public class App(){

A a = new A;

B b = new A;//父类的引用指向了子类

a.test();//A

b.test();//B

}

非静态(重写只跟非静态有关),重写(public)

public class B(){

public  void test(){

sysout("B");

}

}

----------------------------------------------------

public class A extends B(){

@override

public void test(){

sysout("A");

}

}

----------------------------------------------------

public class App(){

A a = new A;

a.test();//A

B b = new A;

b.test();//A

}

重写的小结:快捷键Alt+Enter

  • 需要有继承关系的两个类,子类重写父类的方法(只能重写方法)
  • 方法名必须相
  • 参数列表必须相
  • 修饰符:范围可以扩大 public>protected>defalut>private
  • 抛出异常,范围,可以缩小,但是不能扩大 classNotFoundException-->Exception(大)
  • 子类的方法必须和父类的一样,方法体不同
  • 和返回值有关(返回值类型可以一致;对于引用数据类型来说,子类要小于等于父类(父类是object子类是string可以,反过来不行;))

继承的应用

this调用属性

/**
*父类Father
*子类Son
*测试类Demo
*this调用属性
*this调用方法
**/

//*****************Father*********************

public class Father{
    public String name='jack';
    public int age;

    public void function(){
        sysout(this.name);//father中的this是father类型的
        this.eat();//调用的子类的eat方法,因为,成员方法在调用的时候看的是对象的实际对象(new的谁),this的实际对象Son
    }

    public void eat(){
        sysout('father is eating now');

    }

}

//*******************Son*******************

public class Son extends Father{
    //如果子类里有重名的变量
    public String name='rose';//①

    public void meehod(){
        sysout(this.name);//显示子类的名字,son类中的this类型就是son。
        this.eat();//在son里调用eat方法,就是子类的方法
    }
    
    //子类里也有重名方法
    public void eat(){
        sysout('son is eating now');

    }

}


//********************Demo******************

public class Demo{
    public static void main (string args[]){
        Son son =new Son();
        son.mehtod();//子类中的,name是子类的name
        son.function();//父类继承下来的,name是父类的;this.成员变量,调用的是谁看类型,this在哪个类中,this的类型就是谁;但this.成员方法的时候,是看new的是谁,就是那个对象


        
    }
}
//这时执行son.mehtod(),显示的结果是son的名字,rose
//但如果删掉①,就找不到子类的名字,就往上找父类的,所以显示的结果是父类的Jack
//属性看类,方法看对象!!


this调用的是谁:属性看类,方法看对象

Father father=new Son();//多态的写法

father对象类型是?Father

father对象实际对象是?Son

4.继承之构造器

1)由于构造器的名称必须和类名称一致,所以子类是无法继承构造器的

2)构造器的作用:初始化成员变量

类加载的时候,是先加载父类再加载子类

实例化对象的时候,父类空间优于子类对象的产生(先执行父类的构造器,再执行子类的构造器

每一个构造器里首行都默认有一行super(),调用父类的无参构造方法

要求:父类中必须存在无参构造器,否则默认情况会出错

           super()如果显式创建,也必须在首行

/**
*
*
*
**/

构造器内存图补!!!!11.pm_11

5.java单继承

只能有一个直接父类,但可以有多个子类

具有局限性,后期接口会解决这个局限性

任何类都是有父类的,创建一个类的时候,如果没有显式继承父类,就是默认它的父类是object

6.super

super:指的是子类对象中的父类空间

this:指的是子类对象

用法:super.内容//调用父类的属性或方法

            this.内容//调用自己的属性或者方法

共同点:找不到都会向上一级一级找

          super(实参列表)//调用父类的构造器(对父类空间进行初始化)

          this()调用本类的构造器

特点:都在构造器的第一行,不能同时出现

7.final

最终的,不可修改的访问修饰符

1)修饰类:被final修饰的类不能被继承,String就是final类

/**
*final修饰符修饰的类不能被继承
*
**/
final class super(){
    public void method(){
        
    }
}

2)修饰变量:该变量就变成常量(不能被修改)常量名建议大写用_链接

final修饰成员变量必须要要初始化!

/**
*final修饰变量
*
**/
class super {
    private final String name='Amy'//必须有初始值;final和static谁在前都行

    public void setName(String name){
        this.name=name;//会报错,因为final修饰的变量就变成了常量不允许被修改
    }
}

final修饰局部变量,可以不初始化的

/**
*final 修饰局部变量
*
**/

public void method(){
    final int a;//可以不初始化
    //使用时候第一次赋值就算初始化,之后的算修改
    a=10;//初始化
    a=20;//修改

}

3)修饰方法

该方法不能被重写,重载可以

/**
*
*final修饰方法,方法不允许被重写
**/

class Super{
    public final void function(){
        sysout();
    }

}

class Sub extends Super {
    public void function(){//会报错,方法不允许被重写
    }
}

多态

定义:多态是指,同一行为具有不同的表现形式

前提:1.继承父类或者实现接口

           2.必须有重写

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

/**
*
*
**/

//************************Person类************************
public class Person{
    private int id;
    private String name;

    public void eat(){
        sysout('eating');
    }

}


//************************Employee类************************
public class Employee extends Person{
    private double salary;

    @override
    public void eat(){//重写父类方法
        sysout('eating Employee lunch');
    }

}

//************************Student类************************
public class Student extends Person{
    private double score;

    @override
    public void eat(){//重写父类方法
        sysout('eating Student lunch');
    }

}
//************************Test类************************
public class Test{
    public static void main (String[] args){
        //父类的引用指向子类的对象
        //new Employee();//子类对象
        //new Student();
//正常应该是 Employee employee =new Employee();,但现在左边的引用是写成父类的

        Person per1 = new Employee();//per1对象类型是Person,实际对象是Employee
        Person per2 = new Student();//per2对象类型是Person,实际对象是Student
    }

}

同一个方法,可以根据发送对象的不同而采用多种不同的行为方式:run()编译时才知道调用了谁?

一个对象的实际类型是确定的,但可以指向对象的引用类型有很多

一个对象的实际类型是确定的

//new Student();

//new Person();

//可以指向的引用类型不确定了,父类的引用指向子类(父类可以调子)

//Student(eat方法、run方法)是Person(run方法)的子类

Student a = new Student(); //可执行eat方法、run方法

Person  b = new Student();//可执行run方法

Object  c = new Student();

  • 能执行哪些方法,主要看左边的类型,和右边的关系不大
  • 子类可以调用的方法不是自己的就是继承于父类的
  • 父类可以指向子类,但不能调用子类的方法

多态的注意:

多态是方法的多态

父类和子类,有继承关系 (ClassCastException父子转换异常)

存在条件:继承关系,方法需要重写,父类引用子类对象 Father f1 = new Son();

不能重写的场合:

  • static方法属于类,不属于实例
  • final常量
  • private方法私有不能重写

instanceof (引用类型的强制转换):判断两个类之间是否存在线性父子关系

public void test(){

//Object>String

//Object>Person>Teacher

//Object>Person>Student

Object object = new Student();

sysout(Object instanceof Student);//true

sysout(Object instanceof Person);//true

sysout(Object instanceof Object);//true

sysout(Object instanceof Teacher);//false

sysout(Object instanceof String);//false

Person person = new Student();//主要看对象判断是否有关

sysout(Person instanceof Student);//true

sysout(Person instanceof Person);//true

sysout(Person instanceof Object);//true

sysout(Person instanceof Teacher);//false

//sysout(Person instanceof String);//编译报错

}

类之间的转换

父()-->子()需要强制转换;低转高,自动转换(多态),但可能丢失自己的一些方法

强制转换,是因为多态父类调用不了子类独有的内容,但就是很想调用(少见也要少用)

语法:子类类型 对象名 =(子类类型)父类引用

强转之前要先判断,前面的实际对象是否属于后面的类型

boolean flg=person instanceof Employee;//change要不就和后面的一样,要不就是后面的父类

sysout(flg);//ture

public class test{
    main(){
        Employee employee =new Employee();
        Student student=new Student();
        method(student);
    }


    public static void method(Person person){
        //判断person的实际对象是什么
        if(person instanceof Employee){
            Employee employee =(Employee)person;
            employee.working();
        }else if (person instanceof Student){
            Student student =(Student)person;
            student.study();
        }

    }

}

语法:子类类型 对象名 =(子类类型)父类引用

Person change= new Student();//把change这个对象转换成Student类型,使用Students的类型方法

Student student =(Student)change;//Person转Student 强制转换

student.go();//go()是student里的方法

简写:

((Student)change).go();

  • 父类引用子类的对象
  • 把子类转成父类,向上转型
  • 把父类转成子类,向下转型,强制转换

关键字

native 本地的,原生的,只能修饰方法,修饰的方法可以被重写

不能和abstract一起使用的修饰符?

final 不能一起修饰方法和类

static不能一起修饰方法

native不能一起修饰方法

private不能一起修饰方法

static和final一起使用

修饰方法:可以,因为都不能被重写

修饰成员变量:可以,表示静态常量

修饰局部变量:不可以,static不能修饰局部变量

修饰代码快:不可以,final不能修改代码块

修饰内部类:可以,一起修饰成员内部类,不能一起修饰局部内部类

Object根父类 默认是类的父类

该类中所有的方法可以被任意对象继承下去

构造器:无参构造器,供子类使用

方法:toString()

所有对象,在输出或者拼接的时候,都会默认调用该对象的toString方法

/**
*
*
*
**/


//*******************************toString**********************************
public class Test{
    main(){
        Employee employee =new Employee();
        Object obj =new Object ();//这个对象没有什么意义,供子类使用

        sysout(employee.toString());//输出的是经过处理的地址(object类中的toString方法
        sysout(employee);//和上一行一样输出的经过处理的地址

//所有对象,在输出或者拼接的时候,都会默认调用该对象的toString方法


        String str =new String("abc");
        sysout(str);//输出值abc
    }

}

//**object类中的toString方法
public String toString(){
    return getClass().getName()+"@"+Integer.toHexString(hashCode());
}

class getClass();反映位置,会遇到此方法

功能:返回对象的运行时类型(类加载的时候,会创建一个class对象)

hashCode();

将当前对象,通过哈希算法,得到一个int值,

两对相同对象(地址一样)经过相同的的hash算法,得到的int值是一样的。

两个不同的对象,经过相同的hash算法,得到的int值,不一定不相同

集合--》hashmap集合会遇到

finalize()

垃圾回收机制(自动的不定时回收)

Java中什么样的对象,会被认为是垃圾?没有引用的对象

垃圾对象被回收的时候,会默认调用该对象的finalize方法

目的:让这个对象做一个临终遗言(这个方法不是回收的代码)

equals(Object)

判断两个地址是否一致,实际和==没啥区别

但String类会重写equals,就直接比较值了

Static

代码块

{

}//匿名代码块,赋初始值

static{

//静态代码块,只执行一次

}

静态导入包

package com.java.method;
import static java.lang.Math.random;//静态导入包,关键字static
import static java.lang.Math.PI;

public class Test {
    public static void main(String[] args) {
        System.out.println(Math.random());//正常不导入lang包
        System.out.println(random());//导入lang包后可直接使用
        System.out.println(PI);
    }
}

被关键字final修饰后,就不能被继承了(断子绝孙了 。。。)

四、抽象类

抽象类:用关键字abstract修饰的,只有方法名,没有具体的实现,继承它的子类必须实现(父债子还)

抽象类不能new,只能靠子类去实现,抽象方法必须写在抽象类里

package com.java.method;
//abstract 抽象类:类 extends 类是单继承,接口可以多继承
public abstract class Action {
    //只有方法名,没有方法
    public void doSth(){
        
    }
    //抽象类不能new,只能靠子类去实现
    //抽象方法必须写在抽象类里
}

//---------------------------------------------

package com.java.method;
//抽象的方法,继承他的子类必须实现(父债子还)
public class A extends Action {
    @Override
    public void doSth() {
        System.out.println("...");
    }
}

五、接口

接口:只有规范,自己无法写方法,比抽象类还抽象,约束和实现分离(面向接口编程)接口就是规范,接口的本质就是契约,是面向对象的精髓。(多继承 implements)

抽象类:具体实现和规范(抽象方法)都有(单继承 extends)

普通类:只有具体实现

接口里所有的方法都是public abstract的,接口不能被实例化,因为接口里没有构造方法。

关键词:interface、(实现一个接口,implements 接口,实现了接口就要重写接口里的方法)

package com.java.method;

public interface UserService {
    //接口里的所有定义的方法都是 抽象的public abstract
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);//接口都需要有实现类
}

//--------------------------------------------------

package com.java.method;

public interface Time {
    void time();
}

//---------------------------------------------------

package com.java.method;
//抽象类用extends
//一个类可以实现一个接口,implements 接口
//实现了接口的类,就要重写接口里的方法
public class UserServiceImpl implements UserService,Time{//可以多继承
    @Override
    public void time() {

    }

    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }
}

六、内部类

内部类就是在一个类中再定义一个类,可以通过内部类获取外部类的私有属性 

package com.java.method;

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

    }
    class Inner{
        public void in(){
            System.out.println("这是内部类的方法");
        }

        //获取外部类的私有属性
        public void getID(){
            System.out.println(id);
        }
    }
}

//-------------------------------------------------------------

package com.java.method;

public class Application {
    public static void main(String[] args) {
        Outer outer=new Outer();

        //通过外部类来实例化内部类
        Outer.Inner inner = outer .new Inner ();
        inner.in();
        inner.getID();
    }
}

内部类未完...

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值