java类和对象详细过程(上)

类和对象

面向对象的初步认识

什么是面向对象

java是一门纯面向对象的语言,简称(OOP)在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。用面向对象的思想来涉及程序,更符合人们对事物的认知,对于大型程序设计,拓展以及维护都非常友好。

面向对象与面向对象过程

1.传统洗衣服

拿个盆
放水
放衣服
放洗衣粉
手搓

注重洗衣服的过程,不同衣服洗的方式不一样,晾干时间不一样。
2.现代洗衣服
总共有四个对象:人,衣服,洗衣机,洗衣粉。

类的定义和使用

面向对象程序设计关注的是对象,而对象是现实生活中的实体,比如:洗衣机。但洗衣机,计算机并不认识,需要开发人员告诉计算机什么是洗衣机。
上图就是对洗衣机的简单概述,该过程称为对洗衣机对象(实体)进行抽象(对一个事物的重新认识),但这些简化的抽象结果计算机也不能识别,开发人员可以采用某种面向对象的编程语言来进行描述。

简单认识类

类是用来对一个实体(对象)来进行描述,主要描述该实体(对象)具体有哪些属性(外观尺寸),哪些功能(用来干啥),描述完成后计算机就可以识别了。

比如:洗衣机,他是一个品牌,在Java中可以看成一个类别。
属性:产品品牌,型号,产品重量,外观尺寸。
功能:洗衣,烘干,定时…

类的定义格式

在Java中定义类时需要用到class关键字

//创建类
class ClassName{
  filed; //字段(属性)或者,成员变量
  method;//行为或者成员方法
  }

class为定义类的关键字,ClassName为类的名字,{}为类的主体

class WashMachine{
   public String brand;//小天鹅
   public String trpe;//型号
   //字段  属性
   }
public class washClothes(){//洗衣服
  System.out.println("洗衣功能");
  }
 public class dryClothes(){//脱水
  System.out.println("脱水功能");
  }
  public class settime(){//定时
  System.out.println("定时功能");
  }
   

注意事项:

  • 类名注意采用大驼峰定义。
  • 成员前写法统一为public
  • 不带关键字static

类的实列化

定义一个类,就相当于在计算机中定义一个新的类型,与int double类似,只不过int与double是Java语言自带的内置类型。而类是用户自定义了一个新类型。
用类类型创建对象的过程,称为类的实例化。

public class Test2{
    public static void main(String[] args){
     WashMachine washMachine1=new WashMachine();
     washMachine1.brand="小天鹅";
     System.out.println(washMachine1.brand);
     
     WashMachine washMachine2=new WashMachine();
     washMachine2.brand="一个品牌·";
     System.out.println(washMachine2.brand);    
public class test2{
  public static void main)String[] args){
   Person person1 =new Person();
   person1.name="zhangsan";
   person.eat();
   System.out.println();
   }

注意事项:

  • new关键字用于创建一个对象的实例。
  • 使用.来访问对象中的属性和方法。
  • 同一个类可以创建多个实例。

类和对象的说明

1.类只是一个模型,用来对一个实体进行描述,限定了类有哪些成员。
2.类是一种自定义的类型,可以用来定义变量。
3.一个类可以实例化出多个对象,实例化的对象占用实际的物理空间,储存类成员变量。

this引用

public class TestDate{
   public int year;
   public int month;
   public int day;

   public void setDate(int y,int m,int d){
   year=y;
   month=m;
   day=d;
   }
   public void printDate(){
    System.out.println("年: "+year+"月:"+month+"日:"+day)'
    }
    public static void main(String[] args){
     TestDate testDate1=new TestDate();
     TestDate testDate2=new TestDate();
    TestDate testDate3=new TestDate();
    
    testDate1.setDate(y:1998,m:1,d:9);

    testDate1.printDate();
    }
    

以上代码定义一个日期类,然后main方法中创建三个对象,并通过Date类中的成员方法对对象进行设置和打印,代码整体逻辑非常简单,没有任何问题。
1.形参名不小心与成员变量名相同:

public void setDay(int year,int month,int day){
  year=year;
  month=month;
  day=day;
  }

2.三个对象都在调用setDate和printDate函数,但是这两个函数中没有任何关系对象的说明,setDate和printDate函数如何知道打印的是哪个对象。

什么是this引用

this引用指向当前对象(成员方法运行时调用成员函数方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作是透明的。

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

  public void setDay(int year,int month,int day){
  this.year=year;
  this.month=month;
  this.day=day;
  }
public void printDate(){
   System.out.println(this.year+"/"+this.month+"/"+this.year);
   }
 }

注意:this引用的是调用函数成员的方法。

this引用的特性

1.this的类型:对应类型引用,即哪个对象调用就是哪个对象的引用类型
2.this只能是在成员方法中使用
3.在成员方法中this只能引用当前对象,不能再引用其他变量。
4.this是成员方法的第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责接受。

对象的构造及初始化

如何初始化对象

在Java方法内部定义一个局部变量,必须要初始化,否则会编译失败。

public static void main(String[] args){
   int a;
   System.out.println(a);
   }

要让上诉代码通过编译,非常简单,只需要正式使用a之前,给a设置一个初始值即可。如果是对象

public static void main(String[] args){
   Date d=new Date();
   d.printDate();
   d.setDate(2021,6,9);
   d.printDate();
}  

每次对象创建好后调用SetDate方法才可以将具体的日期设置
局部变量必须要初始化才能使用,为什么字段声明之后没有给值依然可以使用?

构造方法

构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期只调用一次。

构造方法: 方法名(参数列表)(方法体)没有返回值的方法,并且方法名必须与类名保持一致。

  public TestDate(){
     System.out.println("没有参数的构造方法");
 }
  public TestDate(int year,int month,int day){
  this.month=month;
  this.year=year;
  this.day=day;
  System.out.println("有3个参数的构造方法");
  }
  public static void main(String[] args){
  //此处创建了一个Date类型的对象,并没有显示调用的构造方法
  Date d=new Date(2021,6,9);//输出Date(int,int,int)方法被调用了
  d.printDate();//2021-6-9
  }

特性

1.名字必须与类名相同
2.没有返回值类型,设置为void也不行。
3.创建对象时由编译器自动调用,并且在对象的生命周期只调用一次
4.构造方法可以重载(用户根据自己需求提供不同参数的构造方法)

public class Date{
 public int year;
 pulic int month;
 public int day;
 //无参构造函数
 public Date(){
   this.year=1900;
   this.month=1;
   this.day=1;
}//带有三个参数的构造方法

 public void printDate(int year,int month,int day){
    this.year=year;
    this/month=month
    this.day=day;
 }
    

5.如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。

 public class Date{
      public int year;
      public int month;
      public int day;
      } 
public void printDate(){
 System.out.println(year+"-"+month+"-"+day);
 }
public static void main(String[] args){
  Date d=new Date();
  d.printDate();
  }
}

上述Date类中,没有定义任何构造方法,编译器会默认生成一个不带参数的构造方法。
注意:一旦用户定义,编译器则不在生成。
6,构造方法中,可以通过this调用其他构造方法来简化代码。

调用构造函数方法this()
但是要注意:
1.这个写法只能在构造方法中才这样写
2.构造方法当中,不能调用自己
3.只能放在构造方法的第一行

public class Date{
   public int year;
   public int month;
   public int day;
   //无参构造方法--内部给各个成员赋值的初始值,该部分功能与三个参数的构造方法重复
   //此处可以在无参构造方法中通过this调用三个参数的构造方法。
   

this(…)必须是构造方法中第一条语句。
不能形成环

public Date(){
   this(1900,1,1);
}

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

默认初始化

成员变量在没有初始化的时候,都有一个默认值。引用类型的值:都是null。
int 0
float o.of
char ‘\u0000’
boolean false

public class Test{
  public static void main(String[] args){
  Student student =new Student();
  student.print();
  Student student2 =null;//student2 不指向任何对象
public class Date{
  public int year;
  public int month;
  public int day;
public Date(int year,int month,int day){
  System.out.println(this.year);
  System.out.println(this.month);
  System.out.println(this.day);
  }
  public static void main(String[] args){
  //此处a没有初始化,编译报错
  //Error:(24,28)java:可能尚未初始化变量a
  //int a;
  //System.out.println(a);
  Date d=new Date(2021,6,9);
  }
}   

要搞清楚这个过程,就需要知道new关键字背后所发生的一些事情:

Date d =new Date(2021,6,9);

在程序层面只是简单的一条语句,在JVM层面需要做好多事情,下面简单介绍下:
1.检测对象对应的类是否加载,如果没有加载则加载
2.为对象分配内存空间
3.处理并发安全问题
比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突。
4.初始化分配空间
即:对象空间被申请好之后,对象包含的成员已经设置好了初始化。

就地初始化

在声明成员变量时,就直接给出了初始值。

封装

封装的概念

面向对象程序的三个特性:封装,继承,多态。而类和对象阶段,主要研究的就是封装特性。

需求:我想隐藏我的实现内容。

封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

访问限定符

java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据方法结合在一起,更符合人类事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。

NO范围·privatedefaultprotectedpublic
1同一包中的同一类
2同一包中的不同类
3不同包中的子类
4不同包中的非子类

比如:
public:可以理解为一个人的外貌特征,谁都可以看得到。
default:对于自己家族中(同一个包中)不是什么秘密,对于其他人来说就是隐私。
private:只有自己知道,其他人都不知道。
【说明】

  • protected主要是用在继承中,继承部分详细介绍。
  • default权限指:什么都不写的默认权限
  • 访问权限除了可以限定类中成员的可见性,也可以控制类的可见性。
public class Computer{
  private String cpu;
  private String memory;
  public String screen;
  String brand;

public Computer(String brand,String cpu,String memory,String screnn){
  this.brand=brand;
  this.cpu=cpu;
  this.memory=memory;
  this.screen=screen;
  }
  public void Boot(){
  System.out.println("开机---");
  }
   public void PowerOff(){
  System.out.println("关机---");
  }
   public void Surflnternet(){
  System.out.println("上网---");
  }
public class TestComputer{
 public static void main(String[] args){
   Computer p =new Computer("HW","i7","8G","13*14");
   System.out.println(p.head);

封装扩展之包

包的概念

在面对对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组,称为软件包。
在Java中也引入了包,包是对类,接口等的封装机制的体现,是一种对类或者接口等的接口等的很好的组织方式,比如:一个包中的类不想被其他被其他包中不想被其他包中的类使用。包还有一个重要作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。

导入包中的类

java中以提供了很多现成的类供我们使用,列如Date:可以使用java.util.Date导入iava.util这个包中的Date类

public class Test{
  public static void main(String[] args){
  java.util.Date date=new java.util.Date();
  //得到一个毫秒级别的时间戳
  System.out.println(date.getTime());
  }
}  

但是这种写法比较麻烦一些,可以使用import语句导入包。

import java.util.Date;
public class Test{
 public static void main(String[] args){
  Date date= new Date();
   //得到一个毫秒级别的时间戳
   System.out.println(date.getTIme());
   }
}   

如果需要使用java.util中的其他类,可使用import java.util*
在这种情况下需要使用完整的类名

import java.util.*;
import java.sql.*;
public class Test{
  public static void main(String[] args){
  java.util.Date date=new java.util.Date();
  System.out.println(date.getTime());
  }
}

可以使用import static导入包中静态的方法和字段

import static java.lang.Math.*;
public class Test{
  public static void main(String[] args){
  double x=30;
  double y=40;
  //静态导入的方式写起来更方式
  //double result=Math.sqrt(Math.pow(x,2)+Math.pow(y,2));
  double result=sqrt(pow(x,2)+pow(y,2));
  System.out.println(result);
  }
}   

注意事项:import和C++的#include差别很大,C++必须#include来引入其他文件内容,但是Java不需要。import只是为了写代码的时候更方便。import更类似于C++的namespace和using。

自定义包

基本规则

  • 在文件的最下方加上一个package语句指定改代码在哪个包中。
  • 包名需要尽量指定成唯一的名字。
  • 包名要和代码路径相匹配。例如创建com.bit.demo1的包,那么会存在一个对应的路径来储存。
  • 如果一个类没有package语句,则该类被放到一个默认包中。

操作步骤
1.在IDEA中先新建一个包:右键src->新建->包
请添加图片描述

public class Tectcom{
  public static void main(String[] args){
  TestBit testBit =new TestBit();
  Test test =new Test ();
  }
}

2.在弹出的对话框输入包名,例如com.bit.demo1

3.在包中创建类,右键包名->新建->类,然后输入类名即可。

请添加图片描述
4.此时可以看出我们的磁盘上的目录结构已经被IDEA自动创建出来了。
请添加图片描述

5.同时我们也看到了,在新创建的Test.java文件的最上方,就出现了一个package语句。
请添加图片描述

包的访问权限控制举例

Computer类位于com.bit.demo1包中,TestComputer位置com.bit.demo2包中:

package com.bit.demo1;

public class Computer{
 private String cpu;
 private String memory;
 public String screen;
 String brand;
 
 public Computer(String brand,String cpu,String memory,String screen){
   this.brand=brand;
   this.cpu=cpu;
   this.memory=memory;
   }
   package com.bit.demo2;

import com.bite.demo1.Computer;
public class TestComputer{
 public static void main(STring[] args){
  Computer p=new Computer("HW","i7","8G","13*14");
  System.out.println(p.screen);
  //System.out.println(p.cpu);//报错:cpu是私有的,不允许被其他类访问
  //System.out.println(p.brand);//报错:brand是default,不允许被其他包中的类访问。
  }
} 
常见的包

1.java.lang:系统常用基础类
2.java.lang.reflect:java 反射编程包;
3.java.net:进行网络编程开发包。
4.java.util:是java提供的工具程序包。

Static成员

对成员进行实例化

public string name;
public int age;
public string classRoom;//static[教室只有一份]
Student student1 =new Studet("zhngsan","18","301");
Student student1 =new Studet("lisi","6","301");
Student student1 =new Studet("wangwu","28","301");

可以比较,教室都是一致的,假设三个同学是同一个班的,那么他们上课肯定是在同一个教室,那既然在同一个教室,那能否给类中再加一个或=成员变量,来保存同学上课时的教室。答案是否定的。
之前,在Student类中定义的成员变量,每个对象都会包含一份(称之为实例变量),因为需要使用这些信息来描述具体的学生。而现在要表示学生来上课的教室,这个教室属性并不需要每个学生对象中都储存一份,而是需要让所有的学生来共享。在JAVA中,被static修饰的成员,成之为静态变量,也可称之为类成员,其并不属于某个具体的对象。
请添加图片描述
请添加图片描述

static修饰成员变量

static修饰成员变量,称为静态变量,静态变量最大特性:不属于某个具体的变量,是所有对象共享的。
【静态成员变量特性】
1.不属于某个具体的对象,是类的属性,所有对象共享,不储存在某个对象空间中
2.既可以通过对象访问空间,也可以通过类名访问,但一般更推荐使用类名访问
3.类变量储存在方法中
4.生命周期伴随类的一生

静态成员的访问方式:不建议通过对象的引用访问。
建议通过类名的方式进行访问。

System.out.println("教室是:"+student1.classRoom);//不建议

System.out.println("教室是:"+Student.classRoom);

引用可以指向引用吗?不可以
Student student1 =new Student:("zhangsan","18");
Student student2 =student1;
引用只能指向对象:上述代码的意思是:student2这个引用指向了student1这个引用所指向的对象。
请添加图片描述
2.一个引用,能不能指向多个对象?
不可以
3.Person p =null;代表不指向任何对象。

static修饰成员方法

一般类中的数据成员都设置为private,而成员方法设置为public,那设置之后,Student类中classRoom属性相同在类外访问?

public class Student{
 private String name;
 private String gender;
 }
public class TestStudent{
 public static void main(String[] args){
  System.out.println(Student.classRoom);
  }
}
//编译失败
Error:(10,35)java:classRoom在extend01.Student中是控制private访问控制

那static属性应该如何访问?
java中,被static修饰的成员变量方法称为静态成员变量,是类的方法,不是某个对象所特有的。静态成员一般由静态方法访问的。

【静态方法特性】
1.不属于某个特定的对象,是类方法。
2.可以通过对象调用,也可以通过类名。静态方法名()方式调用。
3.不能在静态方法中访问任何非静态成员变量。静态方法 不依赖对象

public static String getClassRoom(){
  Sytem.out.println(this;
  return classRoom;
  }
  //编译失败:Error:(35,28)java:无法从静态上下文中引用非静态变量:this

public static String getClassRoom(){
 age+=1;
 return classRom;
 }
 //编译失败:Error:(35,9)java:无法从静态上下文中引用非静态变量age

4.静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递。

public static String getClassRoom(){
 doClass();
 return classRoom;
 }
 //编译报错:Error`:(35,9)java:无法从静态上下文中引用静态方法doClass()`

静态修饰成员的初始化

注意:静态初始化变量一般不会放在构造方法中来初始化,构造方法的是与对象相关的实例属性
静态成员变量的初始化分为两种:就地初始化和静态代码初始化
1.就地初始化:在定义时直接给出初始值

public class Student{
   private String name;
   private String gender;
   private int age;
   }

2.静态代码初始化:什么是代码块呢?

代码块

代码块概念即分类

使用{}定义的一段代码称为代码块。

  • 普通代码块
  • 构造块
  • 静态块
  • 同步代码块
普通代码块

普通代码块:定义在方法中的代码块

public class Main{
  public static void main(STring[] args){
   //直接使用{}定义,普通代码块
   int x=10;
   System.out.println("x1="+x);
   }
   int x=100;
   System.out.println("x2="+x);
   }
}
//执行结果
x1=10
x2=100
构造代码块

定义类的代码块。也叫:实例代码块,构造代码块一般用于初始化实例成员变量。

public class Student{
  //实例成员变量
  private String name;
  private STring gender;
  }
  public void main(String[] args)
  {
   System.out.println(name);
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿在线码字

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值