类的初始
类中包括:属性,方法。
快速使用
我们都是人,而人的共同特点有很多。
比如:名字,年龄,性别,吃饭,睡觉。。。
// 定义类 public class Person { // 定义属性 String name, gender; int age; // 构造方法 public Person(String name, String gender, int age){ this.name = name; this.gender = gender; this.age = age; } // 定义方法 public void eat(){ System.out.println("在吃饭"); } public void sleep(){ System.out.println("在睡觉"); } }
类的属性
属性就好像人的特征,如:姓名,年龄,性别
声明:
按照变量的声明规则,进行声明即可。也称之为局部变量
类的方法
在 Java 语法中,函数也被称为方法,因为是定义在类下。
一个类可以有多个方法,但是方法下不能嵌套方法。
声明:
/* 访问修饰符 返回值类型 方法名(参数列表){ 逻辑 } */
返回值类型,void 表示没有返回值。
构造方法
- 名称与类名相同
- 没有返回值类型,也不需要void
- 创建对象时,自动调用
public class Person { // 定义属性 String name, gender; int age; // 构造方法 public Person(String name, String gender, int age){ this.name = name; this.gender = gender; this.age = age; } }
方法重载
多个方法相同,根据参数类型位置进行传参。
- 允许类中的方法名一致。
- 参数不能相同。
- 和修饰符,返回值无关。
class Person { public void show() { System.out.println("没有参数的show方法"); } public void show(String name) { System.out.println("我叫:" + name); } public void show(int age) { System.out.println("今年:" + age); } } class Main { public static void main(String[] args) { Person person = new Person(); person.show(); person.show("SPC"); person.show(18); } }
无限传参
- 将形参变量前加 ... 即可
- 位置必须放在,其它形参之后。
class Demo{ // 程序入口 public static void main(String[] args){ System.out.println(add(1,2,3)); // 6 } // 多值相加 public static int add(int ...args){ int sum = 0; for (int i = 0; i < args.length; i++) { sum += args[i]; } return sum; } }
实例化对象
类:就像一个模板。
对象:根据这个模板,产出的对象。
如:张三,李四,他们的名字不一样,但是他们是人,都有属于自己的名字。
快速使用
Person.java
public class Person { // 定义属性 String name, gender; int age; // 构造方法 public Person(String name, String gender, int age){ this.name = name; this.gender = gender; this.age = age; } // 定义方法 public void eat(){ System.out.println(this.name + "在吃饭"); } public void sleep(){ System.out.println(this.name + "在睡觉"); } }
Demo.java
public class Demo { public static void main(String[] args){ Person zhangsan = new Person("张三", "男",22); // 实例化对象 zhangsan.eat(); // 调用 zhangsan 对象的方法 zhangsan.sleep(); Person lisi = new Person("李四", "男", 36); // 实例化对象 lisi.eat(); // 调用 lisi 对象的方法 lisi.sleep(); } }
this
Person.java
public class Person { public Person t(){ return this; } }
Demo.java
public class Demo { public static void main(String[] args){ Person zhangsan = new Person(); // 实例化对象 Person lisi = new Person(); // 实例化对象 System.out.println(zhangsan == zhangsan.t()); // true System.out.println(lisi == lisi.t()); // true System.out.println(zhangsan.t() == lisi.t()); // false } }
总结:
this 是个指向,指向实例化后的对象。
static
可修饰类中属性或方法。
修改静态后由类直接拥有。
静态代码块
特性:
- 初始化类时,会自动执行。
- 只执行一次,不管你创建多少次。
语法:
- static { 初始化一些静态数据 }
怎么才能执行:
- 创建对象
- 创建子类对象
- 访问静态属性
- 调用静态方法
- 主动加载:Class.forName("全限定名")
实例
public class Demo { public static void main(String[] args){ Student.show(); // 访问静态方法 } } class Student{ String name; static int count; // 静态属性 public static void show(){ // 静态方法 System.out.println("学生人数: " + count); } static { // 静态代码块 count = 50; } }
abstract
可以修饰类,也可以修饰方法
修饰类
- 被 abstract 修饰的类称为 抽象类。
- 抽象类意为不够完成,不够具体的类。
- 抽象类对象无法独立存在,即不能 new 对象。
何时定义抽象类?
我们拿动物来举例,有动物这个动物,我们所看见的都是动物的子类,而动物只是一个名词,并没有实际的载体。
这时我们可以将动物,改成抽象类。
修饰方法
- 被 abstract 修饰的方法称为抽象方法
- 类必须是抽象类,才可以创建抽象方法
- 继承抽象类的类,必须重写该抽象类所有抽象方法
实例
public class Demo { public static void main(String[] args){ Animal dog = new Dog("旺财", 6); Animal bird = new Bird("八哥", 3); runDemo(dog); runDemo(bird); } // 多态, 父类作为参数 public static void runDemo(Animal animal){ animal.show(); animal.eat(); } }; // 抽象类 abstract class Animal{ String name; int age; public Animal(String name, int age){ this.name = name; this.age = age; } // 抽象方法 public abstract void eat(); // 普通方法 public void show(){ System.out.println(this.name + "今年" + this.age + "岁了"); } } class Dog extends Animal{ public Dog(String name, int age){ super(name, age); } // 必须重写eat, 因为父类eat是抽象方法 @Override public void eat() { System.out.println("狗狗正在吃东西。。。"); } } class Bird extends Animal{ public Bird(String name, int age){ super(name, age); } // 必须重写eat, 因为父类eat是抽象方法 @Override public void eat() { System.out.println("鸟儿正在吃东西。。。"); } }
final
- 修饰类 ---> 不能被继承
- 修饰方法 ---> 不能被重写
- 修改变量 ---> 不能被修改 ---> 常量
instanceof
判断对象类型。
public class Demo { public static void main(String[] args){ Object a = new A(); System.out.println(a instanceof A); // true System.out.println(a instanceof B); // false } } class A{} class B{}
访问修饰符
类的嵌套
一个类可以嵌套一个类,被嵌套的类我们称它为 内部类。
- 内部类不可以声明:静态属性,静态方法。
- 但是可以声明:静态常量,静态最终方法。也就是 final 关键字。
快速使用
class Outer { String name = "__Outer__"; int age = 1; class Inner{ int age = 2; public void show(){ System.out.println(name); // 没有重名, 可以简写。 System.out.println(Outer.this.age); // 如果重名, 可以使用:外部类名 + this + 名。 System.out.println(this.age); // 加 this 可以更好了理解。 } } } class Test{ public static void main(String[] args) { Outer outer = new Outer(); // 实例化外部类对象 Outer.Inner inner = outer.new Inner(); // 实例化内部类独享 inner.show(); // 内部类方法 } }
静态内部类
- 在内部类前加 static, 正常类是不可以用 static。
- 用法与外部类相同。
class Outer { String name = "__Outer__"; int age = 1; // 静态内部类 static class Inner{ int age = 2; public final void show(){ // 因为是静态内部类, 想要使用外部类的一些属性和方法, 需要实例对象。它相当于一个外部类。 Outer outer = new Outer(); System.out.println(outer.name); // 访问外部类属性 System.out.println(outer.age); System.out.println(this.age); // 访问内部类属性 } } } class Test{ public static void main(String[] args) { Outer.Inner inner = new Outer.Inner(); // 直接调用内部类 inner.show(); // 内部类方法 } }
局部内部类
class Outer { String name = "__Outer__"; public void show(){ // 定义局部类 class Inner{ String name = "__Inner__"; public void sayHi(){ System.out.println(Outer.this.name); // 访问外部类属性 System.out.println(this.name); // 访问局部类属性 } } // 调用具备类 Inner inner = new Inner(); inner.sayHi(); } } class Test{ public static void main(String[] args) { Outer outer = new Outer(); outer.show(); } }
匿名内部类
匿名内部类不是类的嵌套,而是定义了一个接口,不用使用implements去实现,用new的方式
public class HelloWorldAnonymousClasses { /** * 包含两个方法的HelloWorld接口 */ interface HelloWorld { public void greet(); public void greetSomeone(String someone); } public void sayHello() { // 1、局部类EnglishGreeting实现了HelloWorld接口 class EnglishGreeting implements HelloWorld { String name = "world"; public void greet() { greetSomeone("world"); } public void greetSomeone(String someone) { name = someone; System.out.println("Hello " + name); } } HelloWorld englishGreeting = new EnglishGreeting(); // 2、匿名类实现HelloWorld接口 HelloWorld frenchGreeting = new HelloWorld() { String name = "tout le monde"; public void greet() { greetSomeone("tout le monde"); } public void greetSomeone(String someone) { name = someone; System.out.println("Salut " + name); } }; // 3、匿名类实现HelloWorld接口 HelloWorld spanishGreeting = new HelloWorld() { String name = "mundo"; public void greet() { greetSomeone("mundo"); } public void greetSomeone(String someone) { name = someone; System.out.println("Hola, " + name); } }; englishGreeting.greet(); frenchGreeting.greetSomeone("Fred"); spanishGreeting.greet(); } public static void main(String... args) { HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses(); myApp.sayHello(); } }
Lambda表达式
jdk1.8才出现Lambda表达式,只有函数式接口才可以使用Lambda表达式。可在接口上添加@FunctionalInterface,如果接口报错则不是函数式接口。
语法:()->{ }
当大括号 { } 内只有一条语句是可以去掉大括号
import java.io.IOException; public class T { public static void main(String[] args) throws IOException { // 不使用Lambda表达式 Runnable r1 = new Runnable() { @Override public void run() { System.out.println("线程1..."); } }; // 使用Lambda表达式 Runnable r2 = ()->{ System.out.println("线程2..."); }; // 使用Lambda表达式 Runnable r3 = ()-> System.out.println("线程3..."); // 运行 new Thread(r1).start(); new Thread(r2).start(); new Thread(r3).start(); } }