java-1 类和对象

面向对象和面向过程

这是一个抽象的概念。

面向对象的世界里,一切都是对象。

比如我们去买菜的话,需要去确定买什么菜,买多少的菜,然后去菜市场购买。只是我自己至始至终的去完成一件事情,就被称为面向过程,而面向对象中。可能是我让弟弟妹妹去买菜,老板给弟弟妹妹菜,然后菜就到了我的手里。面向对象的几个对象(妹妹,弟弟,老板,菜)相互交互作用后,事情就做好了。

对象需要类,有了类我们就有了对象,对象之间可以交互,就可以面向对象

定义一个类:

class WashMachine{
//WashMachine就是洗衣机这一个类,标准采用大驼峰去书写。

//类里包括两个对象,成员对象(字段/属性)和成员方法(行为)
//成员变量定义到类的内部,行为的外部。
    pubic String brand;
    public String type;
    public double height;
//以上就是洗衣机的属性。

    public void WashClother(){
        System.out.println("洗衣功能");
    }
    public void DryClother(){
        System.out.println("脱水功能");
    }
//以上就是洗衣机的行为。

}

实例化

定义了一个类,就是定义了一个新的类型,和int,double相似。

class Dog{
    public String name;
    public int height;

    public  void Bark(){ 
        System.out.println("汪汪汪");
    }
}
public class L513 {
    public static void main(String[] args) {
    //通过new关键字实例化了一个对象。来调用成员变量
        Dog dog = new Dog();
        System.out.println(dog.height);
        System.out.println(dog.name);
    }
}

dog会在栈上开辟一个空间,里面存放的是类的地址,地址里有成员变量和成员方法。

此时运行结果是0,因为成员变量会默认初始化。

成员变量 是引用数据类型是,初始化成null,是基本数据类型是,初始化成0。

基本数据类型中有两个例外,boolea对应的是false,char对应的是‘\u0000’

前面新定义了两个boole和char类型的成员变量进行打印。 

调用方法同理

class Dog{
    public String name;
    public int height;

    public  void bark(){ 
        System.out.println("汪汪汪");
    }
}
public class L513 {
    public static void main(String[] args) {
    //通过new关键字实例化了一个对象。来调用成员变量
        Dog dog = new Dog();
        System.out.println(dog.height);
        System.out.println(dog.name);

        dog.bark();
    }
}

在实例化对象后,可以在main函数内直接赋值。

        dog.name = "王二狗";
        dog.height=114514;

 实例化可以实例化多个对象。

class Dog{
    public String name;
    public int height;
    public boolean yea;
    public char gushujisama;

    public  void Bark(){
        System.out.println("汪汪汪");
    }
}
class Dog2{
    public String name;
    public int height;
    public boolean yea;
    public char gushujisama;

    public  void Bark(){
        System.out.println("喵喵喵");
    }
}
public class L513 {
    public static void main(String[] args) {
    //通过new关键字实例化了一个对象。
        Dog dog = new Dog();
        Dog2  dog2 = new Dog2();
        dog.name = "王二狗";
        dog.height=114514;

        dog2.name ="张三";
        dog2.height=1919810;
        System.out.println(dog.height);
        System.out.println(dog.name);
        dog.Bark();

        System.out.println("_________________");
        System.out.println(dog2.name);
        System.out.println(dog2.height);
        dog2.Bark();

    }
}

this引用

public class L513 {
    public static void main(String[] args) {
        Date date = new Date();
        Date date2 = new Date();
        Date date3 = new Date();
//        new三个Date的对象。
        date.setDate(1991,2,3);
        date2.setDate(1445,7,3);
        date3.setDate(1,4,6);

    }
}

public class Date{
    public int date;
    public int month;
    public  int year;
    public void setDate(int x,int y, int z){
        year = y;
        month =x;
        date = z;
    }
    public void printdate(){
        System.out.println(year+" "+month+" "+date);
    }
}

如果形参名字不小心和成员相同,

    public void setDate(int year,int month, int date){
        year = year;
        month =month;
        date = date;
    }


但是上面输出的是0;因为setdate里的形参都是局部变量,不是成员变量。

解决方法为:

    public void setDate(int year,int month, int date){
        this.year = year;
        this.month =month;
        this.date = date;
    }

需要引用this关键字。

this关键字

this引用是当前对象的引用,谁调用了方法,谁就是当前的this

this只能在成员方法和构造方法中引用

    public void printdate(){
        System.out.println(this.year+" "+this.month+" "+this.date);
    }
//这里面也可以加this,最好用他防止报错。

第三种赋值方法

前两者已经提及前面内容,

通过成员方法赋值和直接赋值。

第三种就是构造方法(构造器)。

构造方法的方法名和类名保持一致,实例化时有编译器自动调用,且没有返回值。

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

}
class Dog{
    public Dog(){
        System.out.println("构造方法");
//在这里就可以初始化成员变量了。
    }
}

 构造方法可以不带参数,编译器会自动提供一个不带参数的构造方法。但是如果写入了第二个构造方法,就不能屏蔽原来不带参数的构造方法。

public Date(int year,int month,int day){
    this day =day;
    this month = month;
    this year = year;
}

构造方法可以满足方法的重载。每个构造方法只会调用一次

可以通过右键---gengrate---constructor然后选择参数来一键生成构造方法。

this:

this.属性    访问当前对象的属性

this()       调用当前对象的构造方法(必须放到构造方法里面,且是第一行,不能形成环的调用 )

this.func(方法)()    调用当前对象的成员方法

  访问修饰限定符

public
在任何地方,都可以访问他修饰的成员或者类。


protected
在默认的基础上加上不同包的子类。

default
什么都不写时的默认权限,也就是同一个包中的不同类和同一类都可以使用。

private
只能在当前类中访问,在同一个包下的不同文件就不能访问了。

如果想要在同一个包的另一个类访问private,需要提供一个接口

class Date{
    private int year;
    public int month;
    public int day;

    public Date(){
        System.out.println("没有函数的构造方法");
    }
    public Date(int year,int month,int day){
        this.year=year;
        this.month=month;
        this.day=day;
        System.out.println("三个函数的构造方法");
    }
    public void getyear(int year){
        this.year = year;
    }
    public int setYear(){
        return this.year;
    }
//通过getyear和setyear两个接口来实现调用。


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


    }
}
//另一个类中
public class test {
    public static void main(String[] args) {
        Date date =new Date();
        date.day=1;
        date.month=2;
        //date.year=3; 这一行就会报错了
        date.getyear(1999);
        System.out.println(date.setYear());

        System.out.println(date.day);
    }
}

接口也可以在idea里通过右键-- generate -- getters and setters来实现一键生成

 

public class test {
    public static void main(String[] args) {
        Date date =new Date();
        date.day=1;
        date.getyear(1999);
        date.setDay(1888);
        date.setMonth(1777);
//同理去进行赋值和打印。
        System.out.println(date.setYear());
        System.out.println(date.getDay());
        System.out.println(date.getMonth());
        System.out.println(date.day);
    }
}

 包

import java.util.*;
import java.sql.*;
//有时候一个包下会包含重复的类,这个时候需要指定是哪一个包下的类
public class L514 {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();

        java.sql.Date date1 = new java.sql.Date(12);
    }
}

静态包

import java.util.*;
import java.sql.*;
//有时候一个包下会包含重复的类,这个时候需要指定是哪一个包下的类
import static java.lang.Math.*;
//导入一个math静态包

public class L514 {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();

        java.sql.Date date1 = new java.sql.Date(12);
        int a = (int) Math.pow(2,2);
        int b = (int) pow(2,2);
//导入静态包后,可以去掉Math.直接使用
    }
}

一些常见的包

java.lang
系统常用基础类

java.lang.reflect:java
反射编程包

java.net
进行网络编程开发包

java.sql
进行数据库开发的支持包

java.utill
是java提供的工具程序包

java.io
I/O编程开发包

static修饰的成员变量(静态成员变量)和成员方法(类方法)

修饰后,该成员变量不会存在对象里面,而是存在了方法区,他不再属于对象。

因此不需要实例化就可以实现调用。需要通过类名去访问。

class Class{
    public static int name = 1;
}
public class L514 {
    public static void main(String[] args) {
        System.out.println(Class.name);
    }
}

方法同理,但是静态的方法中不能直接访问非静态的数据和方法       

class Student {
    public String name;
    public double score;
    public int age;

    public static void staticFunc() {
        Student student = new Student();
        student.name = "fsa";
//需要通过在静态方法里面new对象后才能进行访问。
//和main函数需要new对象同理。

    }
}

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

或者

    public static void staticFunc(Studen student) {
        Student student = new Student();
        student.name = "fsa";
//把类作为参数传进来也可以实现访问。
    }

static成员变量初始化

一个是就地初始化,另外一个是静态代码块初始化

静态代码块初始化

代码块就是花括号括起来的内容{}

代码块可以分为四种,普通代码块(本地代码块),构造块(实例代码块),静态块,同步代码块。

普通代码块(本地代码块):

public void func(int a){
    System.out.println(a);
    {
        System.out.println("本地代码块");
    }
}

实例代码块 (类的内部,方法外部)

class Student {
    public String name;
    public double score;
    public int age;


    public void staticFunc() {
        Student student = new Student();
        student.name = "fsa";
    }

    {
        System.out.println("实例代码块");
    }
}

静态代码块

class Student {
    public String name;
    public double score;
    public int age;


    public void staticFunc() {
        Student student = new Student();
        student.name = "fsa";
    }

    static{
        System.out.println("静态代码块");
    }
}

一个类中,代码块执行顺序为 静态代码块 实例代码块 本地代码块,静态的最先被加载

如果有多个静态代码块,则要看执行顺序。

如果没有实例化对象,那么之后执行静态的。

静态的只会执行一次。

内部类

定义在一个类或者一个方法内部的类称做内部类

内部类有:

实例内部类

静态内部类

本地内部类

匿名内部类

实例内部类

public class L514 {
    public static void main(String[] args) {
    }
}
class dog{
    public int length;
    public void bark(){

    }

    class body{
        public int heart;
    }
}

//实例内部类中,不能定义静态的成员变量和成员方法
如果要定义static修饰的成员变量 需要在static后面加final修饰
class Dog{
    public int length;
    public void bark(){

    }

    public class Body{
        public int heart;
        public Body(){
            System.out.println("实例内部类的构造方法");
        }
        public void func(){
            System.out.println("实例内部类的方法");
//可以访问同一个类的成员变量,不论是否静态
        }
    }
}

public class L514 {
    public static void main(String[] args) {
       Dog.Body body = new Dog().new Body();
//       外部类类名.内部类 变量 = 外部类引用.new 内部类()
    }
}

如果需要在内部类中访问外部类同名的成员变量,需要用

外部类.this.(成员变量)

的格式进行访问。

如果是静态的则是

外部类.(成员变量)

注意事项

外部类中的任何成员都可以被在实例内部类方法中直接访问。

实力内部类所处的位置和外部类成员位置相同,因此也会受到public等访问限定符的约束。

实例内部类对象必须先有外部类对象的前提下才可以创建

外部类中,不能直接访问实力内部类的成员,要访问需要线创建外部类的对象。

静态内部类

 

class Dog{
    public int length;
    public void bark(){

    }

    static public class Body{
        public int heart;
        public Body(){
            System.out.println("静态内部类的构造方法");
        }
        public void func(){
            System.out.println("静态内部类的方法");
        }
    }
}

    public class L515 {
    public static void main(String[] args) {
        Dog.Body body = new Dog.Body();
        外部类类名.内部类 变量 = new 外部类.内部类()
        body.func();
    }
}

注意 在静态内部类中不能直接访问非静态的外部成员,body里就不能访问dog类的length成员变量

如果需要访问,需要实例化对象或者作为参数传入内部类。

局部内部类

定义在方法里面的类,不能被public等访问限定修饰符修饰。

编译器自动生成类的打印函数:

 

 

class Dog{
    public int length;
    public void bark(){

    }

    static public class Body{
        public int heart;
        public Body(){
            System.out.println("静态内部类的构造方法");
        }
        public void func(){
            System.out.println("静态内部类的方法");
        }

        @Override
        public String toString() {
            return "Body{" +
                    "heart=" + heart +
                    '}';
        }
    }
}

public class L515 {
    public static void main(String[] args) {
        Dog.Body body = new Dog.Body();
        String ret = body.toString();
        //去接收tostring的返回值
        System.out.println(ret);
    }
}

这里定义在了内部类中,外部类也可以定义

还可以通直接打印来输出 


    public class L515 {
    public static void main(String[] args) {
        Dog.Body body = new Dog.Body();
//        body.func();
//        String ret = body.toString();
        System.out.println(body.toString());
    }
}

此时打印的不再是地址,因为重写了tostring,重写后编译器不会调用原有的tostring

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值