文章目录
-
面向对象的初步认知
-
类的实例化
-
this引用
-
对象的构造及初始化
-
封装
-
static 成员
-
代码块
-
内部类
-
对象的打印
一、面向对象的初步认知
在 java 中定义类时需要用到 class 关键字 ,具体语法如下// 创建类class ClassName {fifield ; // 字段 ( 属性 ) 或者 成员变量method ; // 行为 或者 成员方法}class 为 定义类的关键字, ClassName 为类的名字, {} 中为类的主体。类中包含的内容称为类的成员。属性主要是用来描述类的,称之为类的成员属性或者类成员变量。方法主要说明类具有哪些功能,称为类的成员方法
注意:
1. 一般一个文件当中只定义一个类
2. main方法所在的类一般要使用public修饰(注意:Eclipse默认会在public修饰的类中找main方法)
3. public修饰的类必须要和文件名相同
4. 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改。
二、类的实例化
class PetDog{
public String name;
public String color;
public void barks(){
System.out.println("汪汪汪--");
}
public void wag(){
System.out.println("摇尾巴--");
}
}
public class Main{
public static void main(String[] args) {
PetDog dogh = new PetDog(); //通过new实例化对象
dogh.name = "阿黄";
dogh.color = "黑黄";
dogh.barks();
dogh.wag();
PetDog dogs = new PetDog();
dogs.name = "阿黄";
dogs.color = "黑黄";
dogs.barks();
dogs.wag();
}
}
三、this引用
public class TestData{
public int year;
public int month;
public int day;
public void setDate(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
}
public void printDate(){
System.out.println(year+"-"+month+"-"+day);
}
public static void main(String[] args) {
TestData testDate=new TestData();
testDate.setDate(2023,2,27);
/*testDate.year=2023;
testDate.month=2;
testDate.day=27;
*/
testDate.printDate();
}
}
注意:this引用的是调用成员方法的对象。
this引用的特性
四、对象的构造及初始化
在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。
public class Main{
public static void main(String[] args) {
int a;
System.out.println(a);
}
}
对象初始化:
class TestData{
public int year;
public int month;
public int day;
public void setDate(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
}
public void printDate(){
System.out.println(year+"-"+month+"-"+day);
}
public static void main(String[] args) {
TestData testDate=new TestData();
testDate.setDate(2023,2,27);
/*testDate.year=2023;
testDate.month=2;
testDate.day=27;
*/
testDate.printDate();
}
}
public class Main{
public static void main(String[] args) {
TestData data=new TestData();
data.setDate(2023,3,3);
data.printDate();
}
}
构造方法
1. 名字必须与类名相同2. 没有返回值类型,设置为void也不行3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法) 名字相同,参数列表不同,因此构成了方法重载。5.如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。6.构造方法中,可以通过this调用其他构造方法来简化代码7. 绝大多数情况下使用public来修饰,特殊场景下会被private修饰
class Date {
public int year;
public int month;
public int day;
public Date(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
System.out.println("Date(int,int,int)方法被调用了");
}
public void printDate() {
System.out.println(year + "-" + month + "-" + day);
}
}
public class Main{
public static void main(String[] args) {
// 此处创建了一个Date类型的对象,并没有显式调用构造方法
Date d = new Date(2023,3,3);
d.printDate(); //
}
}
注意:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。
不能形成环public Date (){this ( 1900 , 1 , 1 );}public Date ( int year , int month , int day ) {this ();}/*无参构造器调用三个参数的构造器,而三个参数构造器有调用无参的构造器,形成构造器的递归调用编译报错: Error:(19, 12) java: 递归构造器调用*/
public class Date {
public int year;
public int month;
public int day;
// 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复
// 此处可以在无参构造方法中通过this调用带有三个参数的构造方法
// 但是this(1900,1,1);必须是构造方法中第一条语句
public Date(){
//System.out.println(year); 注释取消掉,编译会失败
this(1900, 1, 1);
//this.year = 1900;
//this.month = 1;
//this.day = 1;
}
// 带有三个参数的构造方法
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
}
默认初始化
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);
}
}
数据类型 默认值byte 0char '\u0000'short 0int 0long 0Lboolean falsefloat 0.0fdouble 0.0reference null
就地初始化
public class Date {
public int year = 1900;
public int month = 1;
public int day = 1;
public Date(){
}
public Date(int year, int month, int day) {
}
public static void main(String[] args) {
Date d1 = new Date(2021,6,9);
Date d2 = new Date();
}
}
五、封装
面向对象程序三大特性:封装、继承、多态。
访问限定符
Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符:
class Computer {
private String cpu; // cpu
private String memory; // 内存
public String screen; // 屏幕
String brand; // 品牌---->default属性
public Computer(String brand, String cpu, String memory, String screen) {
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 SurfInternet(){
System.out.println("上网~~~");
}
}
public class Main {
public static void main(String[] args) {
Computer p = new Computer("HW", "i7", "8G", "13*14");
System.out.println(p.brand); // default属性:只能被本包中类访问
System.out.println(p.screen); // public属性: 可以任何其他类访问
// System.out.println(p.cpu); // private属性:只能在Computer类中访问,不能被其他类访问
}
}
注意:一般情况下成员变量设置为private,成员方法设置为public。
自定义包
2. 在弹出的对话框中输入包名, 例如 com.bit.demo1
3. 在包中创建类, 右键包名 -> 新建 -> 类, 然后输入类名即可.
4. 此时可以看到我们的磁盘上的目录结构已经被 IDEA 自动创建出来了
5. 同时我们也看到了, 在新创建的 Test.java 文件的最上方, 就出现了一个 package 语句
Java中常见的包1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。2. java.lang.reflflect:java 反射编程包;3. java.net:进行网络编程开发包。4. java.sql:进行数据库开发的支持包。5. java.util:是java提供的工具程序包。(集合类等) 非常重要6. java.io:I/O编程开发包。
六、static成员
【静态成员变量特性】1. 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中2. 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问3. 类变量存储在方法区当中4. 生命周期伴随类的一生 ( 即:随类的加载而创建,随类的卸载而销毁 )
public class Student {
public String name;
public String gender;
public int age;
public double score;
public static String classRoom = "Bit306";
// ...
public static void main(String[] args) {
// 静态成员变量可以直接通过类名访问
System.out.println(Student.classRoom);
Student s1 = new Student("Li leilei", "男", 18, 3.8);
Student s2 = new Student("Han MeiMei", "女", 19, 4.0);
Student s3 = new Student("Jim", "男", 18, 2.6);
// 也可以通过对象访问:但是classRoom是三个对象共享的
System.out.println(s1.classRoom);
System.out.println(s2.classRoom);
System.out.println(s3.classRoom);
}
}
class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom = "Bit306";
// ...
}
public class Main {
public static void main(String[] args) {
System.out.println(Student.classRoom);
}
}
七、代码块
使用 {} 定义的一段代码称为代码块 。根据代码块定义的位置以及关键字,又可分为以下四种:普通代码块构造块静态块同步代码块
普通代码块:定义在方法中的代码块
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);
}
}
构造代码块
构造块:定义在类中的代码块( 不加修饰符 ) 。也叫: 实例代码块 。 构造代码块一般用于初始化实例成员变量。
public class Student{
//实例成员变量
private String name;
private String gender;
private int age;
private double score;
public Student() {
System.out.println("I am Student init()!");
}
//实例代码块
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main {
public static void main(String[] args) {
Student stu = new Student();
stu.show();
}
}
静态代码块
使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。
public class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom;
//实例代码块
{
this.name = "bit";
this.age = 12;
this.gender = "man";
System.out.println("I am instance init()!");
}
// 静态代码块
static {
classRoom = "bit306";
System.out.println("I am static init()!");
}
public Student(){
System.out.println("I am Student init()!");
}
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
}
}
八、内部类
public class OutClass {class InnerClass {}}// OutClass 是外部类// InnerClass 是内部类
public class A {}class B {}// A 和 B 是两个独立的类,彼此之前没有关系
根据内部类定义的位置不同,一般可以分为以下几种形式:1. 成员内部类(普通内部类:未被static修饰的成员内部类 和 静态内部类:被static修饰的成员内部类)2. 局部内部类(不谈修饰符)、匿名内部类
在外部类中,内部类定义位置与外部类成员所处的位置相同,因此称为成员内部类。
即未被static修饰的成员内部类。
class OutClass {
private int a;
static int b;
int c;
public void methodA() {
a = 10;
System.out.println(a);
}
public static void methodB() {
System.out.println(b);
}
// 实例内部类:未被static修饰
class InnerClass {
int c;
public void methodInner() {
// 在实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员
a = 100;
b = 200;
methodA();
methodB();
// 如果外部类和实例内部类中具有相同名称成员时,优先访问的是内部类自己的
c = 300;
System.out.println(c);
// 如果要访问外部类同名成员时候,必须:外部类名称.this.同名成员名字
OutClass.this.c = 400;
System.out.println(OutClass.this.c);
}
}
public static void main(String[] args) {
// 外部类:对象创建 以及 成员访问
OutClass outClass = new OutClass();
System.out.println(outClass.a);
System.out.println(OutClass.b);
System.out.println(outClass.c);
outClass.methodA();
outClass.methodB();
System.out.println("=============实例内部类的访问=============");
// 要访问实例内部类中成员,必须要创建实例内部类的对象
// 而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类
// 创建实例内部类对象
OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
// 上述语法比较怪异,也可以先将外部类对象先创建出来,然后再创建实例内部类对象
OutClass.InnerClass innerClass2 = outClass.new InnerClass();
innerClass2.methodInner();
}
}
注意:
class OutClass {
private int a;
static int b;
public void methodA(){
a = 10;
System.out.println(a);
}
public static void methodB(){
System.out.println(b);
}
// 静态内部类:被static修饰的成员内部类
static class InnerClass{
public void methodInner(){
// 在内部类中只能访问外部类的静态成员
// a = 100; // 编译失败,因为a不是类成员变量
b =200;
// methodA(); // 编译失败,因为methodB()不是类成员方法
methodB();
}
}
public static void main(String[] args) {
// 静态内部类对象创建 & 成员访问
OutClass.InnerClass innerClass = new OutClass.InnerClass();
innerClass.methodInner();
}
}
注意:
1. 在静态内部类中只能访问外部类中的静态成员
如果确实想访问,我们该如何做?
2. 创建静态内部类对象时,不需要先创建外部类对象
局部内部类
public class OutClass {
int a = 10;
public void method(){
int b = 10;
// 局部内部类:定义在方法体内部
// 不能被public、static等访问限定符修饰
class InnerClass{
public void methodInnerClass(){
System.out.println(a);
System.out.println(b);
}
}
// 只能在该方法体内部使用,其他位置都不能用
InnerClass innerClass = new InnerClass();
innerClass.methodInnerClass();
}
public static void main(String[] args) {
// OutClass.InnerClass innerClass = null; 编译失败
}
}
注意:
1. 局部内部类只能在所定义的方法体内部使用
2. 不能被public、static等修饰符修饰
3. 编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class
九、对象的打印
public class Person {
String name;
String gender;
int age;
public Person(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
public static void main(String[] args) {
Person person = new Person("Jim","男", 18);
System.out.println(person);//打印的是:day20210829.Person@1b6d3586
}
class Person {
String name;
String gender;
int age;
public Person(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
@Override
public String toString() {
return "[" + name + "," + gender + "," + age + "]";
}
public static void main(String[] args) {
Person person = new Person("Jim","男", 18);
System.out.println(person);
}
}
第一种直接打印对象其实是打印对象的地址,第二种通过重写toString方法来打印对象。