本文主要包含了以下几个模块:
1、类和对象的基本内容
2、static关键字
3、构造方法
4、this关键字
5、代码块
6、toString方法
7、private关键字
一、类和对象的基本内容
1、类和对象的关系
声明一个类就是创建一个新的数据类型; 对象是类的实例化,类的实例化就是创建对象的过程。一个类可以实例化多个对象,实例化的对象占用实际的物理空间——存储类成员变量。
2、类的基本组成
类由 class 关键字来声明
class <class_name>{
field; //成员属性(也称成员变量或实例变量),在堆区存储。
method; //成员方法(也称实例方法)
}
使用成员变量: 对象名.成员变量名
使用成员方法: 对象名.成员方法名(参数)
如何创建一个对象 ----> 类名称 引用名称=new 类名称()
public class Practice {
public static void main(String[] args) {
Person per=new Person();
per.name="呼啦";
per.age=18;
per.sex="女";
per.show();
}
}
class Person{
int age;
String name;
String sex;
void show(){
System.out.println("我的名字:"+name+",年龄:"+age+",性别:"+sex);
}
}
类中定义的成员变量都有默认值。
空指针异常:null在java中表示空引用,只有名字,没有保存任何堆内存中的地址,若直接使用值为null的引用去操作 “ . ” 成员变量或方法,会报错。
二、static关键字
出现了static则与对象无关(不能出现在方法中)
static主要修饰以下四个部分
修饰属性 | 类属性、类方法 |
修饰方法 | 类方法、工具方法 |
修饰代码块 | 静态代码块 |
修饰内部类 | 静态内部类 |
(一)修饰属性
1、static修饰的属性、类变量,所有对象共享
当一个实例变量被static修饰时,他就表示类的属性,该类的所有对象共享这个属性,所有对象的属性值都一样。static修饰的属性在JVM的方法区存储,直接通过类名称(类名称.属性名称)就可以访问,无需通过对象访问。如:Person.country
public class Practice {
public static void main(String[] args) {
Person per1=new Person();
per1.show();
Person per2=new Person();
per2.name="呼啦";
per2.age=20;
per2.sex="女";
per2.country="中国"; //修改了country,后面所有的country都被更改了
per2.show();
System.out.println(Person.country);
Person per3=new Person();
per3.show();
}
}
class Person {
int age;
String name;
String sex;
static String country ;
void show(){
System.out.println("我的名字:"+name+",年龄:"+age+",性别:"+sex+" ,来自:"+country);
}
}
当country被static修饰后,所有的对象共用这个属性。一旦country被修改后,后面所有的country都被修改了。
注:调用new Person()来产生Person的对象,先要有Person类才能产生对象。首先要将Person类加载到内存中,Person中所有static变量会被加载到方法区中。
2、final和static的区别
public class Practice {
public static void main(String[] args) {
Person per1=new Person();
per1.show();
Person per2=new Person();
per2.country="中国";
per2.show();
Person per3=new Person();
per3.show();
}
}
class Person {
final int age=18; //age是个常量
String name;
String sex;
static String country; //country是个静态变量
void show() {
System.out.println("我的名字:" + name + ",年龄:" + age + ",性别:" + sex + " ,来自:" + country);
}
}
final修饰的age是常量,在堆区存在,是不可以被修改的。Person的所有对象都有age属性,值为18。 而static修饰的country是个静态变量,在方法区存在;是可以修改的;其次修改后,Person的country都改变了。
在类中定义常量,一般都会使用全局常量,用static final共同修饰。
常量命名规则 :所有单词全部大写,多个单词使用下划线分隔
static final String STUDENT_SCHOOL="西安科技大学"
3、static属性称为类属性,通过类名称直接访问,即没有对象也可以调用(包括该类的null引用)
不会报“空指针异常”。
public class Practice {
public static void main(String[] args) {
Person per1=null;
System.out.println(per1.country);
}
}
class Person{
static String country;
}
(二)修饰方法
1、static修饰方法主要是修饰 类方法和工具类方法,修饰方法时也是通过类名称直接访问,没有对象就可以访问。
2、静态方法能否访问成员变量和成员方法?反之,可以吗?
分析:首先,静态域是没有对象的。其次,成员变量和成员方法必须通过对象访问。
(1)静态方法中是不可以直接调用成员方法和成员属性的(除非在静态类方法中创建一个当前类的对象);静态方法中只能调用静态方法或属性,static家族之间可以相互调用。
(2)在方法中既可以调用成员方法,也可以调用静态方法(此时已经产生该类对象,一定可以访问静态域)。
3、static不能直接修饰一个外部类。因为没有对象,外部无法调用。
4、主方法就是一个静态方法——主方法是一个程序的入口,没有对象就可以直接调用,不用产生对象。假设主方法是成员方法,则必须通过对象调用,没有对象即没有程序入口。
三、构造方法
构造方法是类中非常特殊的一类方法,使用关键字new实例化对象时就是调用该类的构造方法。
1、构造方法的作用就是产生对象:
①为对象在堆中分配空间,②调用对象的构造方法为对象成员变量赋值。
2、构造方法的规则:
①方法名称与类名称完全相同,②没有返回值类型(不是void),③一个类中至少存在一个构造方法,若在类中没有定义,编译器会自动生成一个无参构造。
成员变量的默认值就是在构造方法中实现的。
public class Practice {
public static void main(String[] args) {
Person per=new Person();
}
}
class Person{
String nmae;
int age;
String sex;
public Person(){
System.out.println("Person的构造方法");
}
}
JVM产生对象时调用构造方法,对象实例化结束后,无法再次调用构造方法。
4、构造方法的重载
此时的重载只能是参数的个数不同,因为参数类型已经在类中确定了。
public class Practice {
public static void main(String[] args) {
Person per=new Person();
Person per1=new Person(12,"呼啦");
}
}
class Person{
String nmae;
int age;
String sex;
public Person(){
System.out.println("Person的无参构造方法");
}
public Person(int age,String name){
System.out.println("Person的有参构造:");
System.out.println("name: "+ name+" ,age: "+age);
}
}
四、this关键字
调用当前对象的成员变量 | 表示同名的成员变量 |
调用当前对象的方法 | 普通成员方法 |
构造方法的相互调用 | |
表示当前对象的调用 | 哪个对象调用的,this就指代这个对象 |
1、调用当前对象的成员变量
可以打破就近原则,从类中找同名变量
public class Practice {
public static void main(String[] args) {
Person per=new Person("呼啦",18,"女");
per.show();
}
}
class Person{
String name;
int age;
String sex;
public Person(String name,int age,String sex){
name=name;
age=age;
sex=sex;
System.out.println("Person的有参构造:");
}
public void show(){
System.out.println("name:"+name+",age:"+age+" ,sex:"+sex);
}
}
程序设计中的就近匹配原则
此时的三个成员变量指的是有参构造中的初始值,而并非类中的成员变量,此时,可以使用this关键字,打破就近原则。
使用了this之后,this.name就指代的是类中的成员变量了。
2.1调用普通成员方法
编译器会自动加this(写不写都行)
public class Practice {
public static void main(String[] args) {
Person per=new Person("呼啦",18,"女");
// per.show();
per.fun();
}
}
class Person{
String name;
int age;
String sex;
public Person(String name,int age,String sex){
this.name= name;
this.age=age;
this.sex=sex;
System.out.println("Person的有参构造:");
}
public void show(){
System.out.println("name:"+name+",age:"+age+" ,sex:"+sex);
}
public void test() {
System.out.println("Person类的test成员方法");
}
public void fun(){
this.test();
System.out.println("Person类的fun成员方法");
}
}
2.2构造方法间的相互调用
(1)若不同参数的构造方法间出现了重复的调用,可以使用this(参数)调用其他的构造方法。
(2)this调用其他的构造方法必须放在当前构造方法的首行。
(3)this调用方法不能成环,否则会形成死循环。
public class Practice {
public static void main(String[] args) {
Person per=new Person("呼啦",18,"女");
per.show();
}
}
class Person{
String name;
int age;
String sex;
public Person(){
System.out.println("lalalalalalalala");
}
public Person(String name,int age){
this();
this.name=name;
this.age=age;
}
public Person(String name,int age,String sex){
this(name,age);
this.sex=sex;
}
public void show(){
System.out.println("name:"+name+",age:"+age+" ,sex:"+sex);
}
}
3.this表示对当前对象的引用,当前的属性或方法是哪个对象调用的,this就指代哪个对象
五、代码块
普通代码块 | 定义在方法中,用{ }括起来的 |
成员代码块 | 定义在类中,用{ }括起来的,也叫构造块 |
静态代码块 | 定义在类中,被static修饰的代码块,在类加载时执行一次,与对象无关。 |
同步代码块 |
1、构造块优先于构造方法执行,有几个对象产生就调用几个构造块。
public class Practice {
public static void main(String[] args) {
Animal animal=new Animal();
Animal animal1=new Animal("多多");
}
}
class Animal{
String name;
{
System.out.println("2:Animal的构造块");
}
public Animal(){
System.out.println("1:Animal的无参构造");
}
public Animal(String name){
this();
this.name=name;
}
}
2、静态代码块
public class Practice {
public static void main(String[] args) {
Animal animal=new Animal();
System.out.println("age="+animal.age);
}
}
class Animal{
static int age=10;
static{
age=100;
}
}
static int age:静态变量在方法区中存储,类定义时,age就有初始值10,这个类只是定义了,放入了方法区,还没有加载到内存中。当主方法中使用了Animal这个类,就需要把Animal从方法区加载到内存中---->此时静态代码块就执行了,age的值从10变到了100。
public class Practice {
static{
System.out.println("主类的静态代码块");
}
public static void main(String[] args) {
System.out.println("进入主方法");
}
}
class Animal{
static int age=10;
static{
age=100;
}
}
先加载主类,才能进入主方法。
六、toString方法
当一个引用类型的变量调用println函数打印时,默认输出的都是引用类型的地址。当需要打印这个对象的具体内容时,实现一个toString方法。
public class Practice {
public static void main(String[] args) {
System.out.println(new Animal("呼啦"));
}
}
class Animal{
String name;
public Animal(String name){
this.name=name;
}
public String toString(){
String ret="name:"+this.name;
return ret;
}
}
七、private关键字
面对对象的三大特性:封装、继承、多态
Java面对对象的封装性是通过对成员方法和成员变量的访问控制实现的,访问控制分为四个等级。
私有(private)< 默认(default)< 保护(protected)< 公有(public)
private修饰的属性和方法只能在类的内部可见。若要使用private修饰的成员变量,可以使用间接访问控制——setter和getter方法。
public class Practice {
public static void main(String[] args) {
Person per = new Person("呼啦", 20);
per.show();
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void show() {
System.out.println("name=" + name + " ,age=" + age);
}
public void getName(String num1) {
name = num1;
}
public void setAge(int num) {
age = num;
}
}
补充:
匿名对象:new出来的对象,没有引用指向,使用了一次之后就被JVM销毁了(常用于测试)。