1.什么是面向对象
System.out.println() // 类.对象.方法
2.方法的加深与回顾
2.1 方法的定义
//demo01是一个类 ,里面有一个main方法
/*方法的定义
修饰符 返回值类型 方法名(...){
方法体;
返回值
}
*/
public class demo01 {
//main方法
public static void main(String[] args) {
}
//定义简单的方法
public String sayHello()
{
return "Hello World";
}
public int max(int a,int b)
{
return a > b ? a : b ;//三元运算符
}
}
2.2 方法的调用
- 方法的调用有静态方法 ( s t a t i c ) 、非静态调方法 \textcolor{red}{方法的调用有 静态方法(static)、非静态调方法} 方法的调用有静态方法(static)、非静态调方法
- 也有调用写在自身类里面的方法,或者调用写在其它类里面的方法(简单的,就是用静态与非静态的方法) \textcolor{red}{也有调用写在自身类里面的方法,或者调用写在其它类里面的方法(简单的,就是用静态与非静态的方法)} 也有调用写在自身类里面的方法,或者调用写在其它类里面的方法(简单的,就是用静态与非静态的方法)
2.2.0 写在其它类里的方法
//student类
//静态方法 static//非静态方法
public class Student {
//静态方法
public static void say1(){
System.out.println("学生说话了");
}
//非静态方法
public void say2(){
System.out.println("学生说话了");
}
public int add(int a,int b)
{
return a+b;
}
}
2.2.1 静态方法调用(static)
//方法调用的方法
public class demo02 {
//类中只有属性和方法
//在student类中写的代码,要在另一类中调用
public static void main(String[] args) {
//静态调用 , 类名.方法
Student.say1();//写在其它类里,调用2.2.0的Student类
demo02.c();//写在自己类里的可以 类.方法 。或者直接用c()
}
//方法的另一种,有两非静态方法a可以直接调用b
public void a(){
b();
}
public void b(){
}
//方法的另一种,有两静态方法a可以直接调用b
public static void c(){
d();
}
public static void d(){
}
//方法的另一种,有一个静态、还有一个非静态。无法直接调用
//运行时public static和类一起加载
// public static void e(){
// f();
// }
// //public 类实例化之后才存在
// public void f(){
//
// }
}
2.2.2 非静态方法的调用
public class demo02 {
//在student类中写的代码,要在另一类中调用
public static void main(String[] args) {
//非静态调用,要把类实例化 ,new。实例化就是new出一个对象
//对象类型 对象名 = 对象值
Student student = new Student();
student.say2();
//或者new Student().say2();无参数,无法补全,直接用就行了
//如果有参数
Student student1 = new Student();
int added = student1.add(5, 3);
/*或者 new Student().add(5,3)+alt+enter补全
变成int added1 = new Student().add(5, 3);*/
}
}
2.3 值传递与引用传递
- 值传递:就是类似于c语言的形参与实参
public class demo04 {
public static void main(String[] args) {
//值传递相当于c语言的形式参数,与实际参数
int a=1;
System.out.println(a);//输出:1
demo04.change(a);
System.out.println(a);//输出:1
}
public static void change(int a)
{
a=10;
}
}
- 引用传递:new出一个对象(这个new出来的名字是一个引用变量名)。引用变量名在栈里,指向在堆里的对象
//引用传递
public class demo05 {
public static void main(String[] args) {
//使用Person类
Person person = new Person();//new出一个Person对象,并且把引用值(地址)返回给person
System.out.println(person.name);//输出为:null
System.out.println(person.age);//输出为:0
demo05.change(person);
System.out.println(person.name);//输出为:luchao
System.out.println(person.age);//输出为:1
}
public static void change(Person a)//Person类对象 a
{
//a是一个对象,指向的是--->Person a = new Person();
//对象差不多类似于c语言的指针(地址),可以直接对其修改
a.name = "luchao ";
a.age=1;
}
}
//一个类里面智能有一个public class 。但能有多个class
//定义了一个Person类,有两个属性 name 与 age
class Person{
String name;
int age;
}
3.类与对象的创建
- 类:是抽象的,是对某一类事物的整体描述/定义,类是一个模板
- 对象:是类的具体实例。可以通过new出来
3.1创建与初始化对象
====================================================================================================
java书上p67页讲的好**
对类的实例化分为两步:(实例化就是创建对象,为对象分配存储空间,并同时对对象进行初始化。初始化用构造器) \textcolor{red}{对类的实例化分为两步:(实例化就是创建对象,为对象分配存储空间,并同时对对象进行初始化。初始化用构造器)} 对类的实例化分为两步:(实例化就是创建对象,为对象分配存储空间,并同时对对象进行初始化。初始化用构造器)
- 声明该类型的变量,这个变量没有定义一个对象。它只是能够引用对象的简单变量。(该变量存在栈里)
Jstudent s; //声明一个Jstudent的变量s,s此时的值为null,没有引用任何对象
2.通过new创建一个对象。通过new运算符,创建一个对象的实际的物理拷贝,并且把该对象的引用值(地址)赋给变量s。
new运算符为对象在分配内存空间(在堆里分配),并且返回对象的引用值(系统分配给对象的内存地址)。由于类是一种引用数据类型,因此变量s中存的不是对象本身,而是对象的引用值(地址)。
s= new Jstudent();//通过new实例化对象,把引用值(对象的地址)给s。此时s指向对象,通过s可以得到对象
=========================================================================================================
例子:
创建一个学生 S t u d e n t 类 \textcolor{red}{创建一个学生Student类} 创建一个学生Student类
//学生类
public class Student {
//属性:就是字段。或者说是变量。
String name;
int age;
//方法
public void study()
{
//this代表当前的类
System.out.println(this.name+"在学习");
}
}
//面向对象本质:以类的方式组织代码,以对象的形式封装数据
创建另一个类,这类里面有 m a i n 。对 S t u d e n t 类进行引用 \textcolor{red}{创建另一个类,这类里面有main。对Student类进行引用} 创建另一个类,这类里面有main。对Student类进行引用
//一个项目只存在一个main方法。这个main卸载另一个类里面
public class Application {
public static void main(String[] args) {
//我们要引用学生类。
//由于类是抽象的,要把类实例化new后会返回一个自己的对象
Student xiao_ming = new Student();//学生类实例化成对象小明
Student xiao_hong = new Student();//学生类实例化成对象小红
//对实例化的对象初始化
xiao_ming.name = "小明";
xiao_ming.age = 16;
xiao_hong.name = "小红";
xiao_hong.age = 20;
System.out.println(xiao_ming.name);
System.out.println(xiao_hong.name);
System.out.println(xiao_ming.age);
System.out.println(xiao_hong.age);
}
}
//面向对象本质:以类的方式组织代码,以对象的形式封装数据
3.2创建对象的内存分析(狂神图,这个图也可以理解)
public class Pet {//创建一个宠物类
public String name;//在不同的包里要加public
public int age;
public void shout()
{
System.out.println("叫了一声");
}
}
import com.oop.Demo03.Pet;
public class Application {
public static void main(String[] args) {
Pet dog = new Pet();//类的实例化
dog.name="wang_cai";
dog.age = 3;
dog.shout();
Pet cat = new Pet();
}
}
3.3 构造器
构造器含义:构造器也叫做构造方法,是进行创建对象new必须调用的。
构造方法特点:1.必须和类的名字相同
2.必须没有返回类型,不能写void
3.创建类里面,已经有默认的无参构造器。可以再main中直接new出来
构造器的作用:1使用new关键字必须要有构造器,new的本质是在调用构造器
2.构造器可以初始化对象的值
注意点: 1.定义有参构造智慧化,如果使用无参构造,必须显示定义一个无参构造
2.快捷键:alt+fn+insert快捷生成构造器
例子:
创建一个人 P e r s o n 类 \textcolor{red}{创建一个人Person类} 创建一个人Person类
//构造器
public class Person {
/*一个类即使什么都不写,也存在一个方法(也就是构造方法),这是默认的
存在的构造方法是:public Person(){}
* */
/*
构造器含义:构造器也叫做构造方法,是进行创建对象new必须调用的。
构造方法特点:1.必须和类的名字相同
2.必须没有返回类型,不能写void
3.创建类里面,已经有默认的无参构造器。可以再main中直接new出来
构造器的作用: 1.使用new关键字必须要有构造器,new的本质是在调用构造器
2.构造器可以初始化对象的值
注意点:1.定义有参构造智慧化,如果使用无参构造,必须显示定义一个无参构造
2.快捷键:alt+fn+insert快捷生成构造器
*/
String name;
//显示定义无参构造器.构造器可以实例化初始值
public Person()
{
this.name="luchao";//也可以什么都不写
}
//显示定义有参构造器.构造器可以实例化初始值。
//如果有有参构造,必须显示定义一个无参构造。 一般无参构造是默认的有的,但是有了有参构造必须说明。
public Person(String name)
{
this.name = name;
}
}
创建一个人 m a i n 运行 \textcolor{red}{创建一个人main运行} 创建一个人main运行
//一个项目只存在一个main方法
public class Application {
public static void main(String[] args) {
//Person里面什么都没有,也能通过new实例化一个对象
Person person1 = new Person();//无参构造器
System.out.println(person1.name);//输出:luchao
Person person2 = new Person("wdsadsa");//有参构造器
System.out.println(person2.name);//输出:wdsadsa
}
4.面向对象三大特性(封装、继承、多态)
4.1封装
例子:
创建一个人 S t u d e n t 类 \textcolor{red}{创建一个人Student类} 创建一个人Student类
//封装:封装大部分是对于属性(变量)来的,不对于方法
public class Student {
//private 属性私有 ,无法像public一样被调用
public String name1;//public 可以随意调用
private String name2;//名字
private int id;//学号
private char sex;//性别
private int age;
//提供一些可以操作私人属性的方法
//提供一些public的get 与 set 的方法.用公共方法操作私人属性。
//get获得这个数据
public String getName2()
{
return this.name2;
}
//set给这个数据设置值
public void setName2(String name)
{
this.name2=name;
}
//快捷键 alt+fn+insert
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>120 || age <0)//不合法的相关处理操作
{
this.age=3;
}
else
{
this.age = age;
}
}
}
创建一个 m a i n 运行 \textcolor{red}{创建一个main运行} 创建一个main运行
import com.oop.Demo04.Student;
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
s1.name1 = "a";//public随意调用
//用public的get与set等公共方法来对私人属性操作。
s1.setName2("lucaho");
String n = s1.getName2();
System.out.println(n);
s1.setAge(999);//年龄999,不合法的。可以再方法中进行判定
System.out.println(s1.getAge());//当不合法时候,会进行修改。修改成3
}
}
/*
封装的意义:
1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.提高系统的可维护性
* */
4.2 继承
4.2.1 继承的用法与Object类
例子:
创建一个 P e r s o n 父类 \textcolor{red}{创建一个Person父类} 创建一个Person父类
//继承
//另外final 常量。只有方法才能被重写。 final也可以修饰类 public final class Person 修饰类不可以被继承
//Person 人 父类
//在子类中extends用于继承父类
//快捷键 ctral+H打开树,可以看到各种继承关系。并且会有一个Object类
//在java中所有的类都默认直接或者间接继承Object类
//父类与子类都继承Object,都可以调用相应的Object方法
//子类只能有一个父类,父类可以有多个子类
public class Person {
//public 最高级。子类继承父类方法用public
//protected 受保护
//default 默认 int age
//private 私人,用于父类的属性
private int money =10_000;//继承中,属性基本上是private
public int a=10;//继承中,属性也可以是public共有的
public void say()
{
System.out.println("说了一句话");
}
//对private属性进行修改
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
创建一个 T e a c h e r 子类与 S t u d e n t 子类 \textcolor{red}{创建一个Teacher子类与Student子类} 创建一个Teacher子类与Student子类
//学生 is 人 子类、派生类
//子类继承父类,就会拥有父类的全部方法、属性(除了私有的之外)
public class Student extends Person{//学生继承了人
//子类继承父类的方法
//父类中有say,子类中没写也可以调用
//子类也继承了Object祖父中的方法、属性。
}
//Teacher 也是人 。子类、派生类
public class Teacher extends Person{
}
创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.say();//子类继承父类的方法、属性(父类属性是私有的,父类的属性也可以公有public)。父类中有say,子类中没写也可以调用
//子类继承父类的private属性,并进行相应的修改
student.setMoney(10);
System.out.println(student.getMoney());
//子类继承父类的public
int aa = student.a;
}
}
4.2.2 this与super
super注意点:
super可以在子类中调用父类的方法、构造方法和属性。(属性如果是private不能调用,其它的都可以调用)
1.super调用父类的构造方法,在构造方法中必须是第一个。
2.super必须只能出现在子类的方法、构造方法之中
3.在子类的构造方法中,supper与this不能同时出现
4.子类的构造会无条件调用父类的构造,因为子类的构造中有默认的supper。
5.可以不用写子类的无参构造,如果写了也没事。在子类的无参构造中,是默认有隐藏的supper(),调用父类的无参构造,也可以把supper()明写出来。
6.如果父类中只有有参构造,没有无参构造,就需要明写supper(相应参数);(建议在父类中写的时候,父类的有参构造和无参构造都写)
super与this相比较:
1.this关键字用于访问当前对象,可以用来引用当前对象的属性和方法。this在没有继承也可以使用。
(this相当于是一个对象,不用new的本身就有,是本类中的对象。this可以调用与修改**本类**的一些属性、方法)
super关键字用于访问父类对象,可以用来调用父类的构造方法、成员方法和属性。只能在继承条件下使用
2.this()在构造方法中默认调用本类的构造。supper()在子类的构造方法中默认调用父类的构造。
例子:
创建一个 P e r s o n 父类 \textcolor{red}{创建一个Person父类} 创建一个Person父类
public class Person {
public Person() {//无参构造器
System.out.println("Person无参构造器被执行了");
}
public Person(String name ) {//有参构造器。写了有参必须加无参
System.out.println(name+":Person有参构造器被执行了");
}
public String name= "luchao";//或者 protected String name= "luchao".。两种表示都可以被子类调用
public void print()
{
System.out.println("person");
}
//私有的东西没法被继承
private void s()
{
}
}
创建一个 S t u d e n t 子类 \textcolor{red}{创建一个Student子类} 创建一个Student子类
public class Student extends Person {
public Student() {
//隐藏代码:默认调用了父类的无参构造super();
super();//可以不写,把super()显示出来。调用父类的构造器必须的放在子类构造器第一行
System.out.println("子类的无参构造被执行了");
}
//加入父类中无参构造没了,只有有参构造。子类无法直接调用父类的有参构造,需要加上supper(相应的参数)
private String name = "yanzhiyouxi";
public int ass=3;
public void print() {
System.out.println("Student");
}
public void a()
{
this.ass=4;
System.out.println(this.ass);//this可以对本类中的属性进行修改
}
public void test1(String name)//this与super属性的调用
{
this.a();
System.out.println(name);//输出形参name
System.out.println(this.name);//使用this访问本类中的name
System.out.println(super.name);//使用super访问父类的name
}
public void test2()//this与super方法的调用
{
print();//输出本类中的方法
this.print();//和上一行一样效果,推荐用这个
super.print();//父类方法的调用
}
public void test3()
{
//super.s();//父类中有private权限被锁
//父类私有的东西没法被继承,无法用super调用
}
}
创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行
public class Application {
public static void main(String[] args) {
Student student = new Student();//输出父类与子类的无参构造
student.a();
System.out.println();
student.test1("陆超");//输出: 陆超 yanzhiyouxi luchao
student.test2();//输出: Student Student person
}
}
4.2.2 方法重写
/*重写:子类与父类的方法名必须一致,方法体不同。
前提:1.需要有子父的继承关系。
2.方法名相同,方法体不同。
3.必须是非静态的。
含义:子类重写父类的方法
快捷键 : alt+fn+insert 然后选中override;
特点:
1.方法名必须相同
2.参数列表必须相同
3.修饰符:范围可以扩大,但不能缩小。 修饰符的范围pulic> protected > default>private(注意:有private无法重写)
4.抛出的异常:范围可以被缩小,但不能扩大。
为什么需要重写?
父类的功能子类不一定需要,或者不满足
不能被重写:1.static方法,属于类,不属于实例
2.final 常量。只有方法才能被重写。 final也可以修饰类 public final class Person 修饰类不可以被继承
3.private 无法继承,所以无法被重写
*/
例子:
创建一个 B 父类 \textcolor{red}{创建一个B父类} 创建一个B父类
public class B {
public static void test()//有静态的不是重写
{
System.out.println("B=>test()");
}
public void test1()//子类与父类方法名相同,并且是非静态的,才能重写
{
System.out.println("B=>test()");
}
}
创建一个 A 子类 \textcolor{red}{创建一个A子类} 创建一个A子类
public class A extends B{
public static void test()//有静态的不是重写
{
System.out.println("A=>test()");
}
//写载快捷键alt+fn+insert。@Override这个注解是自动生成的
@Override//注解:有功能的注释
public void test1() {//子类与父类方法名相同,并且是非静态的,才能重写
System.out.println("A=>test()");
}
}
创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行
public class Application {
public static void main(String[] args) {
//父类子类方法都是static静态方法:方法的调用只和左边,定义的数据类型有关
//重写方法与静态毫无关系,只与非静态有关系
A a = new A();
a.test();//输出:A=>test()
//父类的引用B指向了子类A
B b = new A();
b.test();//输出:B=>test()
//重写必须是非静态方法,并且必须是public
//父类、子类方法不是static,是非静态方法。
A c = new A();
c.test1();//输出:A=>test()
B d = new A();//子类重写了父类的方法
d.test1();//输出A=>test()。子类重写了父类
}
}
4.3多态
4.3.1多态的使用
例子:
创建一个 P e r s o n 父类 \textcolor{red}{创建一个Person父类} 创建一个Person父类
public class Person {
public void run()//重写了run
{
System.out.println("Person run");
}
public void eat()
{
System.out.println("eat");
}
}
创建一个 S t u d e n t 子类 \textcolor{red}{创建一个Student子类} 创建一个Student子类
public class Student extends Person{
@Override //alt+fn+insert进行重写
public void run() {//重写了run
System.out.println("son");
}
public viod aaa()//子类中有aaa方法,而父类中无aaa方法。父类可以指向子类,但是不能调用子类的方法。
{
System.out.println("Person aaa");
}
}
创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行
public class Application {
public static void main(String[] args) {
一个对象的实际类型是确定的,都是Student()
//但是,可以指向的引用类型不确定,比如Person、Object。父类的引用指向子类
//对象能执行的方法,主要看看对象左边的类型。
Student s1 = new Student();//子类能调用的方法都是自己的,或者继承父类的
//下面那个是多态写法,父类的引用指向子类。并且有重写的方法
Person s2 = new Student();//父类可以指向子类,但是不能调用子类的方法。这最终还是指向父类自己。
Object s3 =new Student();//祖父辈的引用也指向子类
s2.eat();//输出:eat。s2本来指向的就是父类
s1.eat();//s1中没有eat方法,但是s1可以继承父类,可以调用父类的方法
s2.run();//子类重写了父类的方法,执行了子类。 输出:son
s1.run();// 输出:son
//s2.aaa();//这是错误的,父类可以指向子类,但是不能调用子类的方法。
}
}
4.3.2 instanceof 判断类型 和 类型之间的转换
判断类型。用instanceof判断类型之间是否有关系,有关系true,没关系false。 a对象 instanceof B类型 。a与B是否是包含关系
a可以是B类型的父亲,祖父,儿子,孙子也可以是自己关系。
例子:
创建一个 P e r s o n 父类 \textcolor{red}{创建一个Person父类} 创建一个Person父类
public class Person {
public void run()
{
System.out.println("Person run");
}
}
创建一个 S t u d e n t 子类 \textcolor{red}{创建一个Student子类} 创建一个Student子类
public class Student extends Person{
public void go()
{
System.out.println("Student go");
}
}
创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行(用instanceof来判断类型是否是包含关系)
//判断类型。用instanceof判断类型之间是否有关系,有关系true,没关系false
对象+instanceof +另一个类型.//有关系true,没关系false
public class Application {
public static void main(String[] args) {
//Object>Person>Student
//Object>Person>Teacher
Object obj = new Student();//多态里讲过,爸爸的爸爸也可以指向子类
System.out.println(obj instanceof Student);//true
System.out.println(obj instanceof Teacher);//false
System.out.println(obj instanceof Person);//true
System.out.println(obj instanceof Object);//true
System.out.println(obj instanceof String);//false。String是object的子类,但与Student子类无包含关系
System.out.println("====================================");
Person p = new Student();
System.out.println(p instanceof Student); //true
System.out.println(p instanceof Person); //true
System.out.println(p instanceof Object); //true
System.out.println("====================================");
Student s = new Student();
System.out.println(s instanceof Student);//true。Student与自己是有关系
System.out.println(s instanceof Person);//true。Student与Person是有父子关系
System.out.println(s instanceof Object);//true。Student与Object也是有父子关系,是祖父与孙子之间的关系。
}
}
- 类型转换:
以前学过基本类型的转换,高---->低 需要强制转换。 低----->高,不需要强制转换
//引用类型之间的转换: 父 子 。父—>子 强制转换 ,向下转型 。(引用类型:数组、类、接口)
//子–>父 向上转型,自动转换,向上转型
//方便方法的调用,减少重复的代码
创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行(引用类型的转换)
//以前学过基本类型的转换,高---->低 需要强制转换。 低----->高,不需要强制转换
//类型之间的转换: 父 子 。父--->子 强制转换 ,向下转型
// 子--->父 向上转型,自动转换,向上转型
// 方便方法的调用,减少重复的代码
public class Application {
public static void main(String[] args) {
//类型之间的转换: 父 子 。父--->子强制转换 ,向下转型
//Person父类高的一方 Student子类低的一方
Person s = new Student();
//s.go()是不行的,因为Person中没有go()方法,而在Student中有go方法。
//Person是高类型,Student是低类型,高转低。需要强制转换,使用Student将这个对象转换为Student类型,我们就可以使用Student类型的方法
Student s1 = (Student) s;//将原来Person类的s,强制转换成Student类型的s1
s1.go();
((Student)s).go();//或者把上面两步合在一起 Student s1 = (Student) s;s1.go();
//子--->父 向上转型,自动转换。子类到父类会丢失自己的方法
Student a =new Student();
a.go();
Person p = a;//a是Student类型,是子类。p是Person类型是父类。由子类到父类自动转换
p.run();
}
}
5. static关键字详解
5.1 static的属性和方法的用法
public class Student {
private static int age;//静态变量
private double score;//非静态变量
public void run()//非静态的方法
{
System.out.println("非 static run");
//非静态方法可以访问静态方法
//go();
}
public static void go()//static在使用时是跟类一起加载,在加载时没有非静态方法,所以后面非静态方法需要实例化
{
System.out.println("static go");
}
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.age);//通过对象调用属性
System.out.println(s.score);//通过对象调用属性
System.out.println(Student.age);//通过Student类来调用静态变量age,无法调用非静态变量。
//静态属性多采用类名来调用
Student s1 = new Student();
s1.run();//通过对象调用非静态方法
s1.go();//通过对象调用静态方法
new Student().run();//或者通过类直接调用非静态方法
Student.go();//通过类直接调用静态方法。在同一类中也可以直接用go()
}
}
5.2 static静态代码块
public class Person {//代码块(匿名代码块),创建对象的时候就自己创建了。首先执行
//用于赋初始值
{
System.out.println("匿名代码块");
}
static{//静态代码块,第二个执行
//加载一写初始化设置。类加载的时候直接执行,永久执行一次
System.out.println("静态代码块");
}
public Person(){//构造方法最后执行
System.out.println("构造方法");
}
public static void main(String[] args) {
Person p1 = new Person();//执行结果:匿名代码块 静态代码块 构造方法
System.out.println("============");
Person p2 = new Person();//执行结果: 匿名代码块 构造方法 (stitic代码块只执行一次,所以没有了静态代码块)
}
}
5.3 静态导入包(基本不用,了解就可以)
//很少人这样用
//静态导入包,在main中可以直接用randon,可以不用Math.random
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Test {
public static void main(String[] args) {
System.out.println(Math.random());//输出一个随机数
System.out.println(random());//静态导入包输出一个随机数
System.out.println(PI);//静态导入包输出一个随机数
}
}
//另外final 常量。只有方法才能被重写。 final也可以修饰类 public final class Person 修饰类不可以被继承
6. 抽象类(了解即可)
抽象类的含义:abstract在类、方法前修饰,起到约束作用。让别人来完成重写方法。
抽象类的特点:
1.不能new这个抽象类,只能靠子类去实现它,可以通过new子类来实例化,起到约束的作用。
2.抽象类中可以有普通的方法
3.有抽象方法的类一定是抽象类
抽象类的实质是:抽象的抽象,起到约束作用。
创建一个 A c t i o n 类运行 \textcolor{red}{创建一个Action类运行} 创建一个Action类运行
//抽象类:类。需要去继承。 类可以单继承,但是接口可以实现多继承。
public abstract class Action {//变成抽象类
//约束,让其他人帮忙实现
//abstract抽象方法,只有方法的名字,没有方法的实现。
public abstract void do_something();
}
创建一个 A 类运行 , 用 A 类来继承 A c t i o n 类 \textcolor{red}{创建一个A类运行,用A类来继承Action类} 创建一个A类运行,用A类来继承Action类
//实现Action的dosomething方法
//抽象类的所有方法,继承它的子类,都必须去重写它的方法,除非这个子类也是抽象类
public class A extends Action {
@Override//重写Action类中没有写的方法
public void do_something() {
}
}
7.接口(超级重要)
接口的作用:
1.接口特等的约束
2.定义一些方法,让不同人实现
3.接口的方法都是public abstract
4.常量都是lublic static final
5.接口不能被直接new,接口中没有构造方法。接口想要使用必须靠类来重写接口中的方法
6.implements可以实现多个接口,也就是多个继承
创建一个 U s e r S e r v i c e 接口 \textcolor{red}{创建一个UserService接口} 创建一个UserService接口
//接口为interface来定义
//接口只是来定义的。接口都需要实现类
public interface UserService {
//接口中定义的属性都是常量public static final ,可以不写
int age=99;//一般不再接口中定义常量
//接口中的所有定义方法都是抽象的,都是public abstract。并且public abstract可以在接口中不用写
void add(String name);
void deleat(String name);
void update(String name);
void query(String name);
}
创建一个 T i m e S e r v i c e 接口 \textcolor{red}{创建一个TimeService接口} 创建一个TimeService接口
public interface TimeService {
void timerr();
}
创建一个 U s e r S e r v i c e I m p l 类来实现接口 \textcolor{red}{创建一个UserServiceImpl类来实现接口} 创建一个UserServiceImpl类来实现接口
//接口的实现类,是public class+接口名Impl+implements+接口名
//想要实现接口的类,必须重写接口的方法。实现类可以实现多个接口,有多继承
//抽象类是通过 extends
快捷键ctrl+i可以快速添加方法
public class UserServiceImpl implements UserService,TimeService {//接口可以实现多继承
@Override
public void add(String name) {//UserService接口
}
@Override
public void deleat(String name) {//UserService接口
}
@Override
public void update(String name) {//UserService接口
}
@Override
public void query(String name) {//UserService接口
}
@Override
public void timerr() {//TimerService的接口
}
}
8 内部类(了解即可)
8.1成员内部类
创建一个 O u t e r 外部类类,这个 O u t e r 中有一个内部类 I n n e r \textcolor{red}{创建一个Outer外部类类,这个Outer中有一个内部类Inner} 创建一个Outer外部类类,这个Outer中有一个内部类Inner
public class Outer {//外部类
private int id;
public void out()//外部类方法
{
System.out.println("这是外部类的方法");
}
//==========================================================
public class Inner{//内部类,在一个类中定义一个类
public void in()//内部类的方法
{
System.out.println("这是内部类的方法");
}
public void GETId()//内部类的方法可以活动外部类的私有属性、或者方法
{
System.out.println(id);
out();
}
}
}
创建运行 m a i n ,通过外部类来访问内部类 \textcolor{red}{创建运行main,通过外部类来访问内部类} 创建运行main,通过外部类来访问内部类
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过外部类来实例化内部类outer.new Inner()
Outer.Inner inner = outer.new Inner();
inner.in();
inner.GETId();
}
}
8.2静态内部类
创建一个 O u t e r 外部类类,这个 O u t e r 中有一个内部类 I n n e r \textcolor{red}{创建一个Outer外部类类,这个Outer中有一个内部类Inner} 创建一个Outer外部类类,这个Outer中有一个内部类Inner
public class Outer {//外部类
private int id;
public void out()//外部类方法
{
System.out.println("这是外部类的方法");
}
//==========================================================
public static class Inner{//内部类,在一个类中定义一个类。静态内部类无妨访问非静态的外部类
public void in()//内部类的方法
{
System.out.println("这是内部类的方法");
}
public void GETId()//
{ //下面两个会报错,因为静态类会先加载,无法访问非静态类
// System.out.println(id);
// out();
}
}
}
8.3 局部内部类
public class Outer {
//方法中定义的类,叫做局部内部类
public void method(){
class Inner{
}
}
}
8.4匿名内部类
public class Test {
public static void main(String[] args) {
//没有名字初始化化类,不用将实例保存在变量中
new Apple().eat();
}
}
class Apple{
public void eat()
{
System.out.println("eat");
}
}