一、什么是面向对象
1.面向对象是解决问题的一种思想,主要依靠对象直接拿到交互完成一件事情。
2.就像我们洗衣服,我们不需要关注洗衣机是如何造出来的,我们只需要会使用洗衣机来洗衣服就是可以的,不用关注底层是如何实现的。
二、类
java
class Class {
protected String name;
protected int age;
}
在定义的时候需要使用class为定义类的关键字,"Class"是类的名字,{}中的是类的主体;
java
class Student {
protected String name; // 名字
protected int age; // 年龄
protected String stuld; //学号
}
注意事项:
* 类名采用大驼峰的定义;
* 一般一个文件当中只定义一个类;
* main方法所在的类一般要使用public修饰
* public修饰的类必须要和文件名相同;
三、类的实例化
定义了一个类,就相当于在计算机中定义了一个新的类型(和 c 中的 struce 结构体相似)。用类 (这个类型)来创建对象的过程叫做类的实例化。
* 用new关键字来创建一个对象
* 用 '.' 来访问对象中的属性和方法
* 同一个类可以创建多个对象,实例化出来的对象 占用实际的物理空间,存储类成员变量
* 未实例化的类在内存中不占实际内存,它就像是我们房子的设计图纸,还没有建造房子,原来那块地方就没有按照这个图纸设计好的房子
四、this 关键字
在Java的类中,函数都会默认有一个 this 的关键字,this关键字还可以调用本类中的构造函数。
1.this的类型:对应类类型的引用
2.this只能在"成员方法"中使用,不能在类外面使用
3.在"成员方法"中,this只能引用当前对象,不能引用其他对象
java
class Student {
public String name; // 名字
public int age; // 年龄
public String stuld; //学号
public Student() {
}
public Student(String name, int age, String stuld) {
this.name = name;
this.age = age;
this.stuld = stuld;
}
}
五、对象的构造及初始化
在Java中定义局部变量的时候,不初始化直接使用编译器会报错,但是类的对象在实例化中不初始化确实可以运行的,这是因为在我们不写构造函数的时候,编译器会根据类里的对象类型来自动生成构造函数,给类的属性一个默认值。
java
class Class {
protected String name;
protected int age;
}
public class Text {
public static void main(String[] args) {
// int a;
// System.out.println(a);
//////////////////////////// 会报错上面的 /////////
//////////////////////////// 下面的确实可以运行 ////////
Class c = new Class();
System.out.println(c.name); /// 输出 null
System.out.println(c.age); // 输出 0
}
}
六、构造函数
* 名字必须与类名相同
* 没有返回值,void 也不行
* 创建对象的时候编译器自动调用,并且在对象的生命周期内只调用一次
* 构造方法可以重载
如果我们写了构造方法,那么编译器就不会帮我们生成了,如果我们写的是有参数的构造,但是没有写无参数的构造,这时候调用无参数的构造会出问题。代码块二;
java
class Date {
int year;
int month;
int day;
public Date() {}
public Date(int year) {
this.year = year;
}
public Date(int year, int month) {
this.year = year;
this.month = month;
}
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
}
java
class Flay {
String name;
public Flay(String name) {
this.name = name;
}
}
public static void main(String[] args) {
Flay f = new Flay(); // 无法调用
}
6.1 构造方法中也是可以调用其他构造方法的
就像这样,但是this关键字必须在第一行,又因为如果有继承的话,调用父类的构造是需要使用super关键字,这个关键字也必须在第一行,所以this和super是无法同时存在的。
java
class Date {
int year;
int month;
int day;
public Date() {}
public Date(int year) {
this.year = year;
}
public Date(int year, int month) {
this(year);
this.month = month;
}
public Date(int year, int month, int day) {
this(year, month);
this.day = day;
}
}
6.2 访问限定符
* 一个包就像一个家庭
* public:可以理解为你的做的公开的事情
* protect:可以理解为你和你的同学之间的小秘密,家里人可以知道,别人也可以知道
* defaule:(什么都不写就是default)可以认为是你和自己的家人的秘密,家里的事情别人不能知道
* private:就是你自己的秘密,只有你自己知道,谁都不知道
|---|-----------|---------|---------|-----------|--------|
| | 范围 | private | default | protected | public |
| 1 | 同一包中的 同一类 | 可以 | 可以 | 可以 | 可以 |
| 2 | 同一包中的 不同类 | | 可以 | 可以 | 可以 |
| 3 | 不同包中的 子类 | | | 可以 | 可以 |
| 4 | 不同包中的 非子类 | | | | 可以 |
七、包
7.1 包的概念
为了更好的管理类,把多个类收集在一起成为一组,成为包。包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式; 在同一个工程中允许存在相同名称的类,他们只需要在不同的包中就可以。
7.2 如何导入包
Java中的内置类使用:import java.util."类";
自己的不同包中的类使用:import 包."类";
如果是导入全部的类,就是用: import java.util.*;
java
import java.util.Scanner; // 导入内置类
import demo2.Animal; // 导入自定义类
import java.util.*; // 导入全部的内置类
7.2常见的包
-
java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
-
java.lang.reflect:java 反射编程包;
-
java.net:进行网络编程开发包。
-
java.sql:进行数据库开发的支持包。
-
java.util:是java提供的工具程序包。(集合类等) 非常重要
-
java.io:I/O编程开发包。
八、static成员
8.1 static修饰成员变量
static修饰的成员变量,成为静态成员变量,修饰之后的变量:不属于具体的对象,是所有的对象所共享的,可以直接通过类名来访问,即使通过实例化之后的对象来访问"static修饰的成员变量",也是访问的同一个变量,即使是不同的实例化的对象
java
class Student {
String name;
int age;
static int sum; // 被 static 修饰的成员变量
}
public class Test01 {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(s1.sum); // 打印 0
s1.sum++; // sum++
System.out.println(s1.sum); // 打印 1
System.out.println(s1.sum); // 打印 1
Student.sum++; // sum = 2
System.out.println(Student.sum); // 打印 2
}
}
* 它不属于某个具体的对象,是类的属性,是所有对象(实例化、类)所共享的,不存在某个对象的空间中
* 既可以通过类名来访问,也可以通过实例化的对象来访问
* 类变量存储在方法去
* 生命周期伴随类的一生(即 随类的加载而创建,随类的销毁而销毁)
*** 初始化可以就地初始化 或者是 在静态代码块初始化
java
/////////// 就地初始化 ///////
class Student {
String name;
int age;
static int sum = 10; // 被 static 修饰的成员变量
static void show() { // 被 static 修饰的成员方法
System.out.println("hahhh");
}
void show1(){
System.out.println("dddd");
}
}
////// 静态代码块初始化 /////////
class Student {
String name;
int age;
static int sum; // 被 static 修饰的成员变量
static void show() { // 被 static 修饰的成员方法
System.out.println("hahhh");
}
void show1(){
System.out.println("dddd");
}
///////////////
static {
sum = 20; // 初始化为20
}
////////////////////
}
8.2 static 修饰成员方法
被 static 修饰的成员方法成为静态成员方法,是类的方法,不是某个对象所特有的。
java
class Student {
String name;
int age;
static int sum; // 被 static 修饰的成员变量
static void show() { // 被 static 修饰的成员方法
System.out.println("hahhh");
}
void show1(){
System.out.println("dddd");
}
}
public class Test01 {
public static void main(String[] args) {
Student s1 = new Student();
s1.show(); // 通过实例化的对象可以访问
Student.show(); // 通过类名可以访问
s1.show1(); // 可以
// Student.show1(); // 报错
}
}
-
不属于某个具体的对象,是类的方法,所以里面就没有this关键字
-
可以通过对象的调用,也可以通过类名.静态方法名()方式调用
-
不能在静态方法中访问任何非静态成员变量
-
静态方法中不能调用任何非静态方法,因为非静态方法中有this参数,在静态方法中调用无法传递this引用
-
静态方法(static修饰的方法)无法重写,不能实现多态
九、代码块
* 使用 {} 定义的一段代码称为代码块。(1.普通代码块、2.构造块、3.静态块、4.同步代码块)
java
/////// 1.普通代码块 ///////
public class Test01 {
public static void main(String[] args) {
/////////// 直接使用 {}
{
int x = 10;
System.out.println("x1 = " + x);
}
int x = 100;
System.out.println("x22 = " + x);
}
}
////// 2.构造代码块 ////////
class Teacher {
String name;
int age;
// 构造代码块
{
name = "ssss";
age = 20;
}
}
//////// 3.静态代码块 ////////
class Teacher {
String name;
int age;
static int sum;
// 构造代码块
{
name = "ssss";
age = 20;
}
static {
// name = "小红"; // 报错,因为静态代码块不能访问非静态成员和方法
sum = 20;
}
}
* 静态代码块不管生成多少个对象,都只会执行一次
* 静态成员变量是类的属性,因此是在JVM加载类是开辟空间并初始化的
*如果一个类中包含多个静态代码块,在编译的时候,编译器会按照定义的先后顺序来依次执行(合并)
十、内部类
在java中,可以将一个类定义在另一个或者一个方法的内部,分别为内部类、外部类。
- 定义在class类名{}花括号外部的,即使是在一个文件里,都不能称为内部类。就像这 A 和 B两个类。是不同的类
java
class A{}
class B{}
- 内部类和外部类共用一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件
java
// 外部类
class outClas {
// 实例内部类
public class inClss {
}
// 静态内部类
public static class inClass1 {
}
// 方法内部类 -> 局部内部类
public void func(){
class inClass2{
}
}
}
10.1内部类的实例化
1 . 外部类中的任何成员在实例化的内部类方法中可以直接访问
-
实例内部类所处的位置与外部类成员位置相同,所以也受到public等访问限定符的限定
-
在实例内部类方法中访问同名的成员,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名.this.同名成员 来访问
4.实例内部类对象必须下现有外部类对象前提下才能创建
5.实例内部类的非静态方法中包含了一个指向外部类对象的引用
6.外部类中,不能直接访问实例内部类的成员,如果要访问,必须线创建内部类对象
java
class OutClass {
private int a;
private int c;
public void show() {
a = 10;
c = 10;
System.out.println(a);
System.out.println(c);
}
class InClass {
int c;
public void Inshow() {
a = 100; // 可以直接访问外部类的成员变量
c = 1000;
System.out.println("内" + a);
System.out.println("内" + c);
// 可以直接访问外部成员方法
show();
}
}
}
public class Test02 {
public static void main(String[] args) {
OutClass o = new OutClass(); // 外部类的实例化
OutClass.InClass i1 = new OutClass().new InClass(); // 通过实例化一个外部类之后再 new 内部类对象
OutClass.InClass i = o.new InClass(); // 通过已经实例化的外部类对象直接访问内部类 然后构造一个内部类
}
10.2 静态内部类
被static 修饰的内部类称为静态内部类
1.在静态内部类中只能访问外部类中的静态成员
2.创建静态内部类对象的时候不需要先创建外部类对象
java
class OutClass {
private int a;
private int c;
public void show() {
a = 10;
c = 10;
System.out.println(a);
System.out.println(c);
}
static class InClass {
int c;
public void Inshow() {
// a = 100; // 不可以直接访问外部类的成员变量
c = 1000;
System.out.println("内" + c);
// show(); // 不可以直接访问外部成员方法
}
}
}
public class Test02 {
public static void main(String[] args) {
OutClass o = new OutClass(); // 外部类的实例化
OutClass.InClass i = new OutClass.InClass(); // 内部类直接实例化
}
}
十一、对象的打印
在我们的自定义类型中,我们默认打印的是地址,但是我们想要打印我们想要的结果,就是打印成员变量的时候,不想要在每次打印的时候调用我们写好的 打印成员方法怎么办?
这时候我们只需在类里面重写一个 String toString() 方法就可以实现直接通过类的对象来打印里面的东西。这样每次 System.out.println(stu) 的时候会默认去调用我们这个类里面实现好的 toString 方法来打印
java
// 没有重写toString 打印地址
class Stu {
String name;
int age;
}
public class Test02 {
public static void main(String[] args) {
Stu stu = new Stu();
System.out.println(stu);
}
}
///// 重写之后可以直接打印我们想要的结果 //////////
class Stu {
String name;
int age;
public Stu(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Stu{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test02 {
public static void main(String[] args) {
Stu stu = new Stu("王五", 10);
System.out.println(stu);
}