JavaEE入门级别最全教程2--初学者必看
Posted J哥.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaEE入门级别最全教程2--初学者必看相关的知识,希望对你有一定的参考价值。
接JavaEE入门级别最全教程1--初学者必看
JavaEE入门(3w字)
如果你比较穷,一定要学计算机:计算机一定不是你翻身的行业,但一定会让你的生活变得更好。
我无力改变,只有奋斗,与其被卷掉,倒不如卷掉别人。选对了赛道,努力一把,起码让我过得更好一些。
面向对象与面向过程
// 面向对象,是一种看待问题、解决问题的思维方式。
// 类和对象的关系
类是对象的集合
对象是类中的个体
// 类的设计特征:"姓名",行为:"吃饭"
class 类名是一个标识符,遵循大驼峰命名法
类的设计
package com.laity.basicSyntax.day2.oop;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day2.oop
* @date Date : 2021年11月15日 22:13
* @Description: 第一个类:复仇者类
* <p>
* 关于属性:
* 1.每一个属性当不赋值的时候,是有默认值的
* 2.属性,其实就是一个变量
* 3.但是不推荐一行定义多个变量的形式
*/
public class Avenger
// 使用属性,描述所有对象共有的特征
public String name;
public int age;
public char gender;
public int height;
public int weight;
public static int count; // 用static修饰了 就是静态的属性(是可以被所有对象所共享的值)
// 使用方法,描述所有的对象共有的功能
public void eat() // 非静态方法
public void sleep()
System.out.println(name); // 访问当前对象的名字
System.out.println(age); // 非静态成员可以调用方法
eat();
display();
public void beat()
/**
* 静态方法
*/
public static void display()
System.out.println(count);
display();
// System.out.println(name); // 不能直接访问本类中的 非静态成员。
public static void main(String[] args)
对象的实例化
package com.laity.basicSyntax.day2.oop;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day2.oop
* @date Date : 2021年11月15日 22:25
* @Description: 对象的实例化
*/
public class Program
public static void main(String[] args)
// 需要使用关键字 new 进行实例化
Avenger avenger = new Avenger();
Avenger captionAmerican = new Avenger();
package com.laity.basicSyntax.day2.oop;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day2.oop
* @date Date : 2021年11月15日 22:36
* @Description: 类中的成员访问
* 成员访问:
* 非静态的: 需要使用对象进行访问
* 静态的: 理论上来讲 静态的成员 是需要使用类来访问的,但是实际上,对象也是可以进行访问的
*/
public class Program1
public static void main(String[] args)
// 静态的成员访问
Avenger.count = 10;
// 理论上来讲 静态的成员 是需要使用类来访问的,但是实际上,对象也是可以进行访问的
// 静态的空间是唯一的,都有的对象是可以共享这块空间的
// 虽然静态的属性是可以使用对象来访问,但是实际使用中,依然会用类来访问
Avenger ironMan = new Avenger();
ironMan.count = 100; // 对象调用
Avenger thor = new Avenger();
thor.count = 200;
System.out.println(ironMan.count);
System.out.println(thor.count);
// 静态方法的调用
Avenger.display(); // 用类进行调用
/**
* 非静态的成员访问
*/
public static void nonStatic()
// 1. 访问类中的属性
Avenger ironMan = new Avenger();
ironMan.name = "Laity";
ironMan.age = 18;
ironMan.gender = '男';
ironMan.eat();
ironMan.sleep();
ironMan.beat();
Avenger captionAmerican = new Avenger();
captionAmerican.name = "J哥";
captionAmerican.age = 19;
captionAmerican.gender = '男';
captionAmerican.eat();
captionAmerican.sleep();
captionAmerican.beat();
System.out.println(ironMan.age);
System.out.println(captionAmerican.age);
静态和非静态
使用static修饰的属性、方法,被称为静态属性、静态方法 没有使用static修饰的属性、方法,被称为非静态属性、非静态方法,又被称之为实例属性、实例方法。
// 经验
如果某些属性是属于不同的对象的,每一个对象的值都不同,可以设计为非静态。例如人的名字。
如果某些属性是可以被所有的对象共享的,每一个对象看到的值都是相同的,可以设计为静态。例如对象的数量。
只需记住:
静态成员用类进行访问,非静态成员用对象进行访问。
静态方法中可以直接访问本类中的静态成员,不能直接访问本类中的 非静态成员。
非静态方法中可以直接访问本类中的静态成员,也可以直接访问本类的非静态成员。
开辟空间时间不同,静态开辟的时间早
我们在实际中经常用的是 非静态的(强调的是个体的差异性)
静态的常常用于 工具类(Arrays等)
类是一种自定义的数据类型
// 类,其实是一种自定义的引用数据类型,这种类型可以作用于属性、方法参数、返回值...,之前怎么使用的基本数据类型,就可以怎样使用这种类型。
数据类型Avenger(自定义的 引用数据类型)
package com.laity.basicSyntax.day2.opp2.tmp;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day2.opp2.tmp
* @date Date : 2021年11月15日 23:56
* @Description: 实现案例:上课了,老师让学生做自我介绍
*/
public class Program
public static void main(String[] args)
// 1.实例化相关的对象
Teacher teacher = new Teacher();
Student student = new Student();
// 老师让学生自我介绍
teacher.makeIntroduce(student);
class Teacher
// 老师让某个学生做自我介绍
public void makeIntroduce(Student student)
// 让学生做自我介绍
student.introduceSelf();
class Student
// 这个自我介绍是学生的功能
public void introduceSelf()
System.out.println("大家好,我是XXX,今年XXX岁");
类是一种引用数据类型的体现
// 第一种
public static void main(String[] args)
// 类是一种引用数据类型的体现
Person Laity = new Person();
Laity.name = "Laity";
change(Laity); // 指向的是同一个地址
System.out.println(Laity.name);
public static void change(Person person)
person.name = "Jge";
// 第二种
public static void main(String[] args)
// 类是一种引用数据类型的体现
Person Laity = new Person();
Laity.name = "Laity";
Laity.age = 18;
Cat cat = new Cat();
Laity.cat = cat;
Laity.cat.name = "小白";
Laity.cat.furColor = "white";
cat.name = "小猪";
System.out.println("Laity的猫的名字是:"+Laity.cat.name);
This关键字
// this关键字,用在类的实例方法(非静态方法中)或者构造方法中,表示当前对象的引用。
在类中,属性名字可以和局部变量的名字相同。此时,如果直接使用名字访问,优先访问的是局部变量。因此,此时需要使用this关键字表示对当前对象的引用,访问属性。
// 当成员变量和局部变量重名,可以用关键字this区分
package com.laity.basicSyntax.day2.oop3;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day2.oop3
* @date Date : 2021年11月16日 0:31
* @Description: 自定义一个Person类(this关键字)
*/
public class Person
public String name;
public char gender;
public int age;
public int height;
public int weight;
public void setInfo(String name, char g, int a, int h, int w)
this.name = name; // this.name 属性
age = a;
gender = g;
height = h;
weight = w;
This关键字的省略
// 当需要访问的属性与局部变量没有重名的时候,this关键字可以写,也可以不写。
// 当需要访问的属性和局部变量重名的时候,this关键字必须写,不可以省略。
// 切记new出来的都是堆里的 不是 栈里的
构造方法
// 其实也是一种方法。用于实例化对象,在实例化对象的时候调用
和普通方法的区别
构造方法的名字必须和类名保持一致。
构造方法没有返回值,返回值部分不用写。
构造方法的意义
一般情况下,使用构造方法,是为了在实例化对象的同时,给一些属性进行初始化赋值。
// 构造方法的书写
package com.laity.basicSyntax.day2.oop3;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day2.oop3
* @date Date : 2021年11月16日 18:32
* @Description: 构造方法
*/
public class Student
public String name;
public int age;
public char gender;
public int score;
/**
* 这是Student类中的一个构造方法
* 由于这个构造方法没有参数,因此这样的构造方法又被称为无参构造
*/
public Student()
// 这就是一个构造方法
System.out.println("Student类的无参构造方法被执行了");
/**
* 这是Student类中的一个构造方法
* 这个构造方法由于是有参数的,因此这样的构造方法,被称为 有参构造
*
* @param name 属性值
* @param age 属性值
* @param gender 属性值
* @param score 属性值
*/
public Student(String name, int age, char gender, int score)
System.out.println("Student类的有参构造方法被执行了,姓名为" + name + ",年龄为:" + age + ",性别为:" + gender);
// 构造方法调用
public static void main(String[] args)
// 关于构造方法:构造方法的调用
Student lily = new Student();
// 通过有参构造方法,实例化一个Student对象
Student Laity = new Student("Laity",18,'男',2);
// 构造方法注意事项
如果一个类中没有写构造方法,系统会自动提供一个public权限的无参构造方法,以便实例化对象。
如果一个类中写构造方法了,此时系统将不再提供任何的默认的构造方法。
构造方法中调用构造方法
public Student(String name, int age)
System.out.println("Student类的有参构造方法被执行了,姓名为" + name + ",年龄为:" + age);
this.name = name;
this.age = age;
/**
* 这是Student类中的一个构造方法
* 这个构造方法由于是有参数的,因此这样的构造方法,被称为 有参构造
*
* @param name 属性值
* @param age 属性值
* @param gender 属性值
* @param score 属性值
*/
public Student(String name, int age, char gender, int score)
// 1.这句话必须写在构造方法的第一句话
// 2.不能出现循环调用
this(name, age); // 在一个构造方法中调用其他构造方法
System.out.println("Student类的有参构造方法被执行了,姓名为" + name + ",年龄为:" + age + ",性别为:" + gender);
this.name = name;
this.age = age;
this.gender = gender;
this.score = score;
单例设计模式
// 是由前人准备出来的,用来解决特殊问题而存在的解决思路 单例设计模式:一个类中有且只有一个对象。在程序的任意模块,获取到这个类的对象,是相同的对象。 单例设计模式分为: 饿汉式单例 和 懒汉式单例
饿汉式
package com.laity.basicSyntax.day3.oop3;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day3.oop3
* @date Date : 2021年11月16日 23:07
* @Description: 单例设计模式(单例类) 无论在任意地方,这个类的对象,有且只有一个 饿汉式单例
*/
public class Boss
// 私有化构造方法,杜绝从外面实例化的可能性
private Boss() // 创建一个无参构造方法
System.out.println("实例化了一个Boss对象");
// 私有的,静态的,当前的对象,并实例化
// 这个对象的实例化,是在类第一次被加载到内存中的时候开辟
private static Boss instance = new Boss();
// 给外界提供一个方法,提供一个public权限的方法,用来返回当前类的对象
public static Boss getBoss()
// 如果设计成非静态的外部拿不到对象
// 需要保证这里的对象 是唯一的对象;无论这个方法被调用多少次 返回的都是相同的对象
return instance;
package com.laity.basicSyntax.day3.oop3;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day3.oop3
* @date Date : 2021年11月16日 23:08
* @Description: 运行单例位置
*/
public class Program
public static void main(String[] args)
// 1.获取一个类的对象
// Boss boos = new Boss(); // 实例化一个类,但是行不通
for (int i = 0; i < 100; i++)
Boss.getBoss();
懒汉式
package com.laity.basicSyntax.day3.oop3;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day3.oop3
* @date Date : 2021年11月17日 17:13
* @Description: 懒汉式单例
*/
public class Monitor
// 私有化构造方法,杜绝从外面实例化的可能性
private Monitor() // 创建一个无参构造方法
System.out.println("实例化了一个Monitor对象");
// 私有的,静态的,当前的对象,并不实例化(什么时候用什么时候实例化)
// 这个对象的实例化,是在类第一次被加载到内存中的时候开辟
private static Monitor instance;
// 给外界提供一个方法,提供一个public权限的方法,用来返回当前类的对象
public static Monitor getMonitor()
// 如果设计成非静态的外部拿不到对象
// 需要保证这里的对象 是唯一的对象;无论这个方法被调用多少次 返回的都是相同的对象
if (instance == null)
instance = new Monitor();
return instance;
包的概念
/**
* 包:就是起到了组织代码的作用,可以将功能相关的类,放到一个包中
* 包名是一个标识符 需要遵循小驼峰命名法 包与包之间如果存在嵌套(包含)的关系,需要用点 来进行分隔
* package 写在一个文件的最上方 表示这个文件属于哪个包中
* import 导入指定的类到当前文件中,表示可以直接访问其他包中的类(只能从最外层的包开始导:就是不能按相对路径导入)
* java.lang:java的基础语法。 这个包中的类 是可以直接使用的(已经被默认导入了)
* import java.util.Scanner;
* import java.util.Arrays;
**/
面向对象(继承)
// 父类将属性和行为赠与子类
// 继承的使用场景
如果一个类已经不满足我们使用需求时(功能拓展),使用继承。
继承语法:
~class 子类 extends 父类
继承的应用
产生继承关系后,子类可以使用符类中的属性和方法,也可以定义子类独有的属性和方法。
继承的好处
提高代码的复用性、提高代码的拓展性
继承的特点
Java是单继承!一个类只能有一个父类!
// Animal.java
package com.laity.basicSyntax.day3.inherit.inherit1;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day3.inherit.inherit1
* @date Date : 2021年11月17日 22:34
* @Description: 作为父类
*/
public class Animal
// 使用属性
public String name;
public int age;
public String gender;
// 使用方法
public void eat();
public void sleep();
public void beat();
// Dog.java
package com.laity.basicSyntax.day3.inherit.inherit1;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day3.inherit.inherit1
* @date Date : 2021年11月17日 22:36
* @Description: 子类
*/
public class Dog extends Animal
// Program
package com.laity.basicSyntax.day3.inherit.inherit1;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day3.inherit.inherit1
* @date Date : 2021年11月17日 22:37
* @Description: 继承的特点以及使用
*/
public class Program
public static void main(String[] args)
// 1.实例化一个Animal对象
Animal animal = new Animal();
// 2.进行成员访问
animal.name = "animal";
animal.gender = "male";
animal.age = 18;
animal.eat();
animal.sleep();
animal.beat();
// 3.实例化一个Dog对象
Dog dog = new Dog();
// 4.成员访问
dog.name = "dog";
dog.age = 10;
dog.gender = "male";
dog.eat();
dog.sleep();
dog.beat();
访问权限修饰符
// private private int privateVariable; // private私有权限
// default() int defaultVariable; // 默认权限
// protected protected int protectedVariable; // 受保护的权限
// public public int publicVariable;
访问权限修饰符,就是修饰符、属性的访问级别
当前类 | 同胞其他类 | 跨包子类 | 跨包其他类 | |
---|---|---|---|---|
private | √ | × | × | × |
default(不能写出,不写权限,默认就是这个权限) | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ | √ |
方法重写
// 子类可以继承到父类的中的属性和方法,但是有一些方法,子类的实现与父类的方法可能实现的不同。 // 当父类提供的方法已经不能满足子类的需求时,子类中可以定义与父类相同的方法。 // 此时,子类方法完成对父类方法的覆盖,又叫重写(Override)
package com.laity.basicSyntax.day3.inherit.override;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day3.inherit.override
* @date Date : 2021年11月18日 13:16
* @Description: 父类
*/
public class Animal
/**
* 定义了所有的动物都会叫
*/
public void bark()
System.out.println("bark~");
/**
* 当父类提供的方法已经不能满足子类的需求时,子类中可以定义与父类相同的方法。
* 方法重写
*/
class Dog extends Animal
public void bark()
System.out.println("汪汪汪~");
class Cat extends Animal
public void bark()
System.out.println("喵喵喵~");
@Override
一个注解,进行重写前的校验。校验这个方法是否是一个重写的方法。如果不是重写的方法,则直接报错。
public class Animal
/**
* 定义了所有的动物都会叫
*/
public void bark()
System.out.println("bark~");
class Dog extends Animal
@Override
public void bark()
System.out.println("汪汪汪~");
重写的注意事项
-
方法名字必须和父类的方法名字相同
-
参数列表必须和父类一致
-
方法的访问权限需要大于等于父类方法的访问权限
-
方法的返回值类型需要小于等于父类方法的返回值
Super关键字
有时候,子类重写父类的方法的时候,并不是要对父类的实现全盘推翻,而是对父类的方法进行拓展。
父类的方法中的实现仍然需要,但是还需要在父类方法的基础上进行拓展的实现,此时就需要使用super关键字调用父类的方法。
public class Animal
/**
* 定义了所有的动物都会叫
*/
public void bark()
System.out.println("bark~");
class Cat extends Animal
@Override
public void bark()
super.bark(); // 调用父类的实现
System.out.println("喵喵喵~");
打印结果:
bark~
喵喵喵~
继承中的构造方法
package com.laity.basicSyntax.day3.inherit.constructor;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day3.inherit.constructor
* @date Date : 2021年11月18日 13:58
* @Description: 继承中的构造方法
*
* 子类对象在实例化的时候,需要优先实例化从父类继承的部分
* 体现:子类对象在实例化的时候,优先实例化父类部分,这个过程中默认调用父类中的无参构造方法,由此会导致一些问题
* 问题:
* 如果父类没有无参构造方法,或者父类的无参构造方法的访问权限不足,会导致子类对象无法实例化
* 解决:
* 1.访问权限不足:修改父类的访问权限
* 2.如果是父类中没有无参构造方法:
* 2.1 给父类添加无参构造
* 2.2 使用 super()手动调用父类中存在的构造方法
*/
public class Animal
public Animal()
System.out.println("Animal类的无参构造方法执行了");
class Dog extends Animal
public Dog()
System.out.println("Dog类的无参构造方法执行了");
Final关键字
-
可以修饰变量 表示这个变量的值不能改变 常量
-
可以修饰类 表示这个类是一个最终类,无法被继承(没有子类)
-
可以修饰方法 表示这个方法是最终方法,无法被重写
public final class Animal public final void main(String[] args) System.out.println("我是最终类(没有子类),也是最终方法(不能重写)");
Object类
Object类是java中类层次的根类,所有的类都直接或者间接的继承自Object
toString(快捷键alt+insert)
package com.laity.basicSyntax.day3.inherit.object;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day3.inherit.object
* @date Date : 2021年11月18日 14:27
* @Description: Object类
* <p>
* Object类是java中类层次的跟类,所有的类都直接或者间接的继承自Object
* 快捷键 ctrl + f12
* toString *****返回一个对象的字符串表示格式,当需要把这个对象转型为字符串的时候,会自动调用这个方法
* equals *****
* getClass 获取一个用来描述指定的类的Class对象,简单来说就是获取一个对象的类型
* hashCode 集合讲
*/
public class ObjectTest
public static void main(String[] args)
// toString
// equals
Animal animal = new Animal("laity",10,"男");
// getClass():获取一个用来描述指定的类的Class对象,简单来说就是获取一个对象的类型
Class<? extends Animal> aClass = animal.getClass();
System.out.println(aClass.getName()); // 获取类的名字
System.out.println(animal);
class Animal
private String name;
private int age;
private String gender;
public Animal(String name, int age, String gender)
this.name = name;
this.age = age;
this.gender = gender;
/**
* toString 返回一个对象的字符串表示格式,当需要把这个对象转型为字符串的时候,会自动调用这个方法
*
* @return 返回的是一个字符串表示形式
*/
@Override
public String toString()
return " name=" + name + ",age=" + age + ",gender=" + gender+ " ";
equals(快捷键):面向对象比较
* 自定义等值比较的规范 * 1.如果地址相同,则一定要返回true * 2.如果obj是null,则一定要返回false * 3.如果两个对象的类型不同,则一定要返回false * 4.如果 a.equals(b)成立,则b.equals(a) 也必须成立 * 5.如果 a.equals(b)成立,则b.equals(c)成立,则 a.equals(c)也必须成立
== 是地址比较
package com.laity.basicSyntax.day3.inherit.object;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day3.inherit.object
* @date Date : 2021年11月18日 14:27
* @Description: Object类
* <p>
* Object类是java中类层次的跟类,所有的类都直接或者间接的继承自Object
* 快捷键 ctrl + f12
* toString
* equals 对象的比较
* getClass
* hashCode 集合讲
*/
public class ObjectTest
public static void main(String[] args)
// toString
// equals
Animal animal = new Animal("laity", 10, "男");
// getClass():获取一个用来描述指定的类的Class对象,简单来说就是获取一个对象的类型
Class<? extends Animal> aClass = animal.getClass();
System.out.println(aClass.getName()); // 获取类的名字
System.out.println(animal);
Animal animal1 = new Animal("laity", 10, "男");
// equals
boolean ret = animal.equals(animal1);
System.out.println(ret);
class Animal
protected String name;
protected int age;
protected String gender;
public Animal(String name, int age, String gender)
this.name = name;
this.age = age;
this.gender = gender;
public Animal()
// 无参构造
// equals方法
/**
* 自定义规则,实现两个对象的等值比较规则
* @param obj 需要比值的对象
* @return 返回的结果
*
* 自定义等值比较的规范
* 1.如果地址相同,则一定要返回true
* 2.如果obj是null,则一定要返回false
* 3.如果两个对象的类型不同,则一定要返回false
* 4.如果 a.equals(b)成立,则b.equals(a) 也必须成立
* 5.如果 a.equals(b)成立,则b.equals(c)成立,则 a.equals(c)也必须成立
*/
@Override
public boolean equals(Object obj)
if (this==obj)
return true;
if (obj == null|| obj.getClass() != this.getClass())
return false;
// 将参数obj强制转型为当前的类型,否则将无法访问属性
Animal o = (Animal)obj;
// 依次比较每一个属性值,是否都是完全相同的
return name.equals(o.name) && age == o.age && gender.equals(o.gender);
/**
* toString 返回一个对象的字符串表示格式,当需要把这个对象转型为字符串的时候,会自动调用这个方法
*
* @return 返回的是一个字符串表示形式
*/
@Override
public String toString()
return " name=" + name + ",age=" + age + ",gender=" + gender + " ";
class Dog extends Animal
@Override
public String toString()
return "Dog" +
"name='" + name + '\\'' +
", age=" + age +
", gender='" + gender + '\\'' +
'';
面向对象(多态)
多态的概念
-
生活中的“多态”,是指 客观事物在人脑中的主观体现
-
主观意识上的类别,与客观存在的事物,存在 is a 的关系时,即形成 多态
举例:主观上的类别看成狗 客观上的事物时哈士奇---->就是多态(在人脑中的不同体现)
程序中的多态
-
父类引用指向子类对象,从而产生多种形态。
-
二者存在直接或者简介的继承关系时,父类引用指向子类的对象,即形成多态。
-
父类引用仅能访问父类所声明的属性和方法,不能访问子类独有的属性和方法。
对象转型
向上转型
对象由子类类型,转型为父类类型,即为向上转型
-
向上转型是一个隐示转换,一定会转型成功 (我把哈士奇看成一条狗)。
-
向上转型后的对象,只能访问父类中定义的成员,不能访问子类中的独有成员。
向下转换
由父类类型转为子类类型 ( 存在失败的可能性): 我把这条狗看成哈士奇->不一定 也可能是哈士奇
-
需要进行强制类型转换,是一个显示转换。
-
如果失败了,会出现 ClassCastException 异常。
-
向下转型后的对象,可以访问子类中独有的成员。
public class Program
public static void main(String[] args)
// 1. 父类的引用可以指向子类的对象
// Animal animal = new Dog(); // 这个类似 我在大街上看到一条哈士奇,但是我只把它当作一条狗
// 2. 向上转型
Dog dog = new Dog();
Animal animal = dog;
// 3. 向下转型
HaShiQi hashiqi = (HaShiQi) dog; // 如果说它本来就是一只哈士奇才会成功
// 会报异常 ClassCastException
public class Program
public static void main(String[] args)
// 1. 父类的引用可以指向子类的对象
// Animal animal = new Dog(); // 这个类似 我在大街上看到一条哈士奇,但是我只把它当作一条狗
// 2. 向上转型
Dog dog = new Dog();
Animal animal = dog;
// 3. 向下转型
Dog dog1 = new HaShiQi();
HaShiQi hashiqi = (HaShiQi) dog1; // 如果说它本来就是一只哈士奇才会成功
instanceof关键字
进行类型检查:检查某一个对象是不是指定的类型
package com.laity.basicSyntax.day4.polymorphism.ploymorphism2;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day4.polymorphism.ploymorphism2
* @date Date : 2021年11月29日 18:20
* @Description:
*/
public class Program
// 需求:某动物园刚刚开业,需要录入动物信息
// 信息:名字,年龄,如果动物是老虎还需要额外的录入老虎的性别
// 录入系统,简化为控制台输出
public static void main(String[] args)
load(new Tiger());
load(new Wolf());
load(new Monkey());
load(new Lion());
load(new QQ());
public static void load(Animal animal)
// 如果是老虎
// instanceof关键字 进行类型检查:检查某一个对象是不是指定的类型
if (animal instanceof Tiger)
Tiger tiger =(Tiger)animal; // 向下转型
System.out.println("老虎的名字=" + tiger.name + ",老虎的年龄=" + tiger.age+",老虎的性别="+ tiger.gender);
else
System.out.println("name=" + animal.name + ",年龄=" + animal.age);
class Animal
String name;
int age;
class Tiger extends Animal
String gender;
class Wolf extends Animal
// 狼
class Monkey extends Animal
// 猴子
class Lion extends Animal
// 狮子
class QQ extends Animal
// 企鹅
多态中的方法重写
当向上转型后的对象,调用父类中的方法。如果这个方法已经被子类重写了,此时调用的就是子类的重写实现!
package com.laity.basicSyntax.day4.polymorphism.ploymorphism3;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day4.polymorphism.ploymorphism3
* @date Date : 2021年11月29日 19:23
* @Description: 多态中的方法重写
*/
public class Test
public static void main(String[] args)
Animal animal = new Animal();
animal.bark(); // bark~
Dog dog = new Dog();
dog.bark();
Animal animal1 = new Dog(); // 向上转型
animal1.bark(); // Won~
Cat cat = new Cat();
class Animal
public void bark()
System.out.println("bark~");
class Dog extends Animal
@Override
public void bark()
System.out.println("Won~");
class Cat extends Animal
@Override
public void bark()
System.out.println("Meow~");
抽象类与接口
抽象类 abstract
抽象类的概述
程序,是用来描述现实世界,解决现实问题的。 不可被实例化 可以没有抽象方法,但有 抽象方法的 必须 为抽象类。 抽象类有构造器,子类调用 抽象类 都 作为 父类使用 抽象类有 属性 和 方法 抽象类的子类 必须 实现抽象方法或者把自己设为抽象类。
// 定义一个抽象类
package com.laity.basicSyntax.day4.abstractUsage;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day4.abstractUsage
* @date Date : 2021年11月29日 21:41
* @Description: abstract 抽象类的定义
*
* 抽象类是没有对象的(子类是可以继承到的)
* 抽象类不能实例化对象,只是为了给所以的子类进行公共部分的定义
*/
public abstract class Animal // abstract
// 抽象类可以定义属性
public String name;
public int age;
// 也可以定义方法,行为
public void sleep()
public void eat()
// 也可以定义构造方法
抽象方法
被abstract修饰的方法被称为抽象方法。
抽象方法只能定义在抽象类中。
抽象方法只能声明,没有实现。
抽象方法只能包含在抽象类中。
抽象方法的定义
public abstract class Animal // abstract
// 抽象类可以定义属性
public String name;
public int age;
// 也可以定义方法,行为
// 如果有个方法,所有的子类都在重写,那么这个方法在父类中没有必要的
public void sleep()
public void eat()
// 也可以定义构造方法
// 实现抽象方法(被abstract修饰的方法被称为抽象方法。)
// 只能包含在抽象类中
public abstract void bark();
抽象类的实现方法
非抽象类在继承中来自一个抽象父类的同时,必须重写实现父类中所有的抽象方法。因此,抽象类可以用来做一些简单的规则指定。
在抽象类中制定一些规则,要求所有的子类必须实现,约束所有的子类的行为。
场景:就是指定一些简单的规则(因为类是单继承的,所有由局限性)
接口 Interface
宏观上来讲,接口是一种标准。例如,我们生活中常见的USB接口。电脑通过USB接口连接各种外设的设备,每一个接口不用关心连接的外设设备是什么,只要
这个外设的设备实现了USB的标准,就可以使用接口进行这样的复杂的规则指定。
微观上来讲,接口是一种能力和约定
-
接口的定义:代表了某种能力。(类似于生活中的合同)
-
方法的定义:能力的具体要求。(类似于合同中的条款)
从程序上讲,接口代表了某种能力,类似于生活中的合同。而在接口中定义的各种方法,表示这个能力的具体要求,类似于合同中的条款。
(一个类可以实现多个接口,同样不能创建对象,但是也可以引用,具备object所具有的方法)
接口中没有构造方法、构造代码段、静态代码段。
(class改成interface一样的效果) 属性默认 public static final 方法默认 public abstract 实现接口使用implements 接口可以多继承 类可以同时继承和实现接口,继承在前。
接口的定义
package com.laity.basicSyntax.day4.InterfaceUsafe;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day4.InterfaceUsafe
* @date Date : 2021年11月29日 23:32
* @Description: 第一个接口
*
* 方法:接口中的方法默认的修饰符是 public abstract(可写可不写)
* 属性: 接口中的属性默认的修饰符是 public static final
*/
public interface MyFirstInterface
// 接口中可以定义:
// 1.方法
void myInterfaceMethod();
// 2.属性
int a = 10;
抽象类和接口的区别
// 基本区别 抽象类中可以有抽象方法,而接口中所有的方法必须是抽象的 一个类可以实现(implements)多个接口,但只能继承一个抽象类(extends) 抽象类可以有构造方法,而接口内不能有构造方法 抽象类中的抽象方法除了private都可以,而接口中的默认public abstract 抽象类中可以包含静态方法,接口中不能。 抽象类中的属性可以是任意类型的修饰符,接口中只能是public static final // 应用区别 抽象类:在代码实现方面发挥作用,可以实现代码的重用。(抽象工厂模式) 接口:更多的是在系统框架设计方法发挥作用。(多态)
接口的实现 implements
package com.laity.basicSyntax.day4.InterfaceUsafe;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day4.InterfaceUsafe
* @date Date : 2021年11月29日 23:51
* @Description: 调用接口的类
*/
public class MyInterfaceImpl implements MyFirstInterface // alt + enter
@Override
public void myInterfaceMethod()
接口的实现增强
package com.laity.basicSyntax.day4.InterfaceUsafe;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day4.InterfaceUsafe
* @date Date : 2021年11月29日 23:52
* @Description:
*/
public interface MyInterface
void method1();
void method2();
void method3();
String toString();
class Superclass
class Subclass extends Superclass implements MyInterface
// 一个接口的实现和继承是可行的
@Override
public void method1()
@Override
public void method2()
@Override
public void method3()
多个接口的实现
一个类收到多种条件的限制
package com.laity.basicSyntax.day4.Interfaced;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day4.Interfaced
* @date Date : 2021年11月30日 0:05
* @Description:
*/
public interface MyInterface
void method1();
void method2();
void method3();
interface MyInterface1
void method4();
void method5();
interface MyInterface2
void method6();
/**
* 一个类可以实现多个接口,只需要将实现的所有的接口以逗号进行分割即可,接口之间的先后顺序没影响
* 如果一个类实现了多个接口,则必须要所有的接口中的所有的抽象方法都重写实现
* 注意事项:
* 1.如果多个接口中有相同的方法: 则在实现类中只实现一次即可
* 2.如果多个接口中有同名,参数也相同,返回值不同的方法:此时这两个接口是不能同时实现的
* 3.
*/
class MyInterfaceImpl implements MyInterface,MyInterface1,MyInterface2
@Override
public void method1()
@Override
public void method2()
@Override
public void method3()
@Override
public void method4()
@Override
public void method5()
@Override
public void method6()
接口的继承
类是单继承,而接口是多继承的。(一个接口可以有多个父接口。而子接口可以继承到所有的父接口中的成员。)
package com.laity.basicSyntax.day4.Interfaced1;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day4.Interfaced1
* @date Date : 2021年11月30日 0:17
* @Description:
*/
public interface Cooker // 厨师
void cook(); // 会做饭
void buy(); // 会买菜
void clean(); // 会刷碗
interface HouseKeeping // 家政人员
void wash(); // 洗衣服
void saodi(); // 会扫地
interface GirlFriend extends Cooker,HouseKeeping
class Person implements GirlFriend
@Override
public void cook()
@Override
public void buy()
@Override
public void clean()
@Override
public void wash()
@Override
public void saodi()
接口的多态
接口的引用,也是可以指向实现类的对象。与类的多态相似,同样存在向上转型和向下转型。
-
向上转型:实现类类型 转成为 接口类型。(类转接口)
-
是一个隐示转换,不需要任何的修饰
-
向上转型后的接口引用,只能访问接口中的成员。
-
-
向下转型:接口类型 转成为 实现类类型 (接口转类)
-
是一个现实转换,需要强制类型转换。
-
向下转型后的实现类引用,将可以访问实现类中的成员。
-
接口的新特性
在java8中,为接口添加了两个新特性
-
static方法:可以在接口中定义静态方法,静态方法不是抽象方法,是有实现部分的。同时这个静态方法,只能由当前的接口调用,实现类是不能
使用的。
interface Myinterface
public static void method
System.out.println("接口中静态方法的实现");
-
default方法:修饰接口中的方法,default修饰的方法可以添加默认的实现部分。此时实现类在实现接口的时候,对于这些方法可以重写,也可以不
重写。(不重写按照原来的执行,重写了按照重写的执行)
interface Myinterface
public default void method
System.out.println("接口中的方法默认实现方式");
接口的回调
内部类
即定义在类内的类。在java中,可以在类的内部再定义一个完整的类。
-
内部类编译后,可以生成独立的字节码文件 .class
-
内部类可以直接访问外部类的私有成员,而不是破坏封装。
-
可为外部类提供必要的内部功能组件。
内部类的分类
内部类,按照定义的位置和修饰符不同,可以分为:
-
成员内部类
-
静态内部类
-
局部内部类
-
匿名内部类
成员内部类
概念:在类的内部定义,与实际变量、实际方法同级别的类。
使用
-
外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。
-
Outer outer = new Outer();
-
Inner inner = outer.new.Innter();
特点
-
书写位置:与属性、方法平级别,且没有使用static修饰的类
-
访问权限:内部类可以任意的访问权限
-
成员内部类中,不能写静态属性、静态方法。
-
编译之后生成的字节码文件格式:外部类$内部类.class
-
实例化对象,需要借助外部类的对象完成。
示例代码
// OuterClass.class
package com.laity.basicSyntax.day5.clnnerClass.aMember;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day5.clnnerClass.aMember
* @date Date : 2021年11月30日 19:27
* @Description: 成员内部类
* <p>
* 访问权限:内部类是作为外部类的一个成员,访问权限可以为是任意权限。
* 类中的成员定义:成员内部类中,不允许定义静态的成员(静态属性,静态方法)
*/
public class OuterClass
public String name;
// 内部类的定义
public class InnerClass
public String name;
public void show(String name)
System.out.println("参数name=" + name);
System.out.println("内部类属性name=" + this.name);
System.out.println("外部类属性name=" + OuterClass.this.name);
// Program.class
package com.laity.basicSyntax.day5.clnnerClass.aMember;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day5.clnnerClass.aMember
* @date Date : 2021年11月30日 19:27
* @Description:
*/
public class Program
public static void main(String[] args)
// 1.外部类对象实例化
OuterClass outerClass = new OuterClass();
// 2.访问外部类中的属性
outerClass.name = "outerClass";
// 3.实例化一个内部类的对象
OuterClass.InnerClass innerClass = outerClass.new InnerClass(); // 类型为OuterClass.InnerClass
// 4.访问内部类的属性
innerClass.name = "innerClass";
// 5.调用内部类的方法
innerClass.show("parameter");
// 输出结果
参数name=parameter
内部类属性name=innerClass
外部类属性name=outerClass
静态内部类
概念:在类的内部定义,与实例变量、实例方法同级别的,使用static修饰的类。
使用:不依赖外部对象,可以直接创建或通过类名访问。
Outer.Inner inner = new Outer.Inner();
特点
-
书写位置:与属性、方法平级别,且使用关键字 static 修饰的类
-
访问权限:内部类可以任意的访问权限
-
静态内部类中,可以写静态属性、静态方法、属性、方法、构造方法。。。
-
编译之后生成的字节码文件格式:外部类$ 内部类.class
-
实例化对象,不需要借助外部类的对象完成。
示例代码
// OuterClass.class
package com.laity.basicSyntax.day5.clnnerClass.bStatic;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day5.clnnerClass.bStatic
* @date Date : 2021年11月30日 19:57
* @Description: 静态内部类
*/
public class OuterClass
public String name;
public static String name1;
/**
* 静态内部类
*/
public static class InnerClass
// 非静态的属性
public String name;
// 静态的属性
public static int age;
// 方法
public void show(String name)
System.out.println("参数name = "+name);
System.out.println("内部类的属性name = "+this.name);
System.out.println("外部类的属性name = "+"是访问不到的");
System.out.println("外部类的静态属性name1 = "+ OuterClass.name1);
// Program.class
package com.laity.basicSyntax.day5.clnnerClass.bStatic;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day5.clnnerClass.bStatic
* @date Date : 2021年11月30日 20:06
* @Description:
*/
public class Program
public static void main(String[] args)
// 实例化内部类对象
OuterClass.InnerClass innerClass = new OuterClass.InnerClass(); // 不需要外部类对象
// 成员访问
OuterClass.name1 = "outerClass";
innerClass.name = "innerClass";
innerClass.show("parameter");
// 运行打印结果
参数name = parameter
内部类的属性name = innerClass
外部类的属性name = 是访问不到的
外部类的静态属性name1 = outerClass
局部内部类
概念:是定义在外部类的方法中,作用范围和创建对象范围仅限于当前方法。(与成员内部类、静态内部类都不太一样)
特点
-
局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final。
-
不能使用访问权限修饰符修饰。
-
书写位置:书写在一个类的方法内部,作用域仅限于当前方法。
-
局部内部类,编译后生成的字节码文件格式:外部类$ 序号 内部类名.class
实例代码
// Program.class
package com.laity.basicSyntax.day5.clnnerClass.cLocal;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day5.clnnerClass.cLocal
* @date Date : 2021年11月30日 20:48
* @Description: 局部内部类
*/
public class Program
public static void main(String[] args)
innerClassTest();
public static void innerClassTest()
// 定义一个变量
// 如果在一个局部内部类中,使用到了局部变量,那么这个局部变量默认会被定义为 final
int a = 10;
/**
* 局部内部类
* 访问权限:什么权限都没有,都不可以写
*/
class InnerClass
public String name;
public int age;
// 构造方法
public InnerClass()
public void show()
System.out.println("局部内部类的show方法");
System.out.println("a=" + a);
// a = 20;
// 对象实例化
InnerClass innerClass = new InnerClass();
innerClass.show();
匿名内部类
概念:没有类名的局部内部类
特点
-
一切特征与局部内部类相同。
-
必须继承一个父类或者实现一个接口。
-
定义类、实现类、创建对象的语法合并,只能创建一个改类的对象。
示例代码
package com.laity.basicSyntax.day5.clnnerClass.dAnonymous;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day5.clnnerClass.dAnonymous
* @date Date : 2021年11月30日 21:07
* @Description: 匿名内部类
*/
public class Program
public static void main(String[] args)
// 实例化一个对象
// 这就是一个匿名内部类
// 其实,这里实例化的是Person类的一个匿名子类的对象,并实现了向上转型。
Person laity = new Person()
// 匿名内部的类体--->是Person的子类对象
@Override
public void walk()
// 可以看成Override没有报错
System.out.println("我是laity");
super.walk(); // 调用父类的方法
;
// 方法调用
laity.walk();
// 定义一个方法
class Person
public void walk()
System.out.println("Person中的walk");
枚举
枚举的概念
枚举也是一种自定义的数据类型,是一种引用数据类型。枚举经常用来被描述一些取值范围有限的数据。
枚举的基本定义和使用
枚举的定义:定义枚举类型,需要使用到关键字 enum 。枚举的名字是一个标识符,遵循大驼峰命名法。
// 枚举的定义以及赋值
// Gender.class
package com.laity.basicSyntax.day5.dEnum;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day5.dEnum
* @date Date : 2021年11月30日 23:01
* @Description: 性别枚举
*/
public enum Gender
MALE,FEMALE
enum MALE
JAN,FEB,MAR,APR,MAY,JUN,AUG,SEP,OCT,NOV,DEC
enum Weekday
MON, TUS, WED, THU, FRI, SAT, SUN
// Program.class
package com.laity.basicSyntax.day5.dEnum;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day5.dEnum
* @date Date : 2021年11月30日 23:05
* @Description:
* 怎样定义一个枚举变量,怎样对枚举变量进行赋值
*/
public class Program
public static void main(String[] args)
// 1.定义一个枚举类型的变量
Gender gender;
// 2.给一个枚举类型的变量进行赋值
gender = Gender.MALE;
Weekday day = Weekday.WED;
枚举中的成员定义
枚举的分析:枚举,其实可以认为是object类的一个最终子类。不能被其他的类、枚举继承。
public class Program
public static void main(String[] args)
// 1.定义一个枚举类型的变量
Gender gender;
// 2.给一个枚举类型的变量进行赋值
gender = Gender.MALE;
Weekday day = Weekday.WED;
// 验证枚举是Object的最终的子类
// day.toString()
Object obj = day; // 转型
枚举中属性的定义:(非静态我用对象,静态的我用枚举类型进行访问)
// Gender.java
public enum Gender
// 枚举里面的值通常都是大写的
MALE,FEMALE;
// 定义一个非静态属性
public String description;
// 定义了一个静态的属性
public static int count;
// Test.java
package com.laity.basicSyntax.day5.dEnum;
/**
* @author : Laity
* @Project: JavaLaity
* @Package com.laity.basicSyntax.day5.dEnum
* @date Date : 2021年11月30日 23:21
* @Description:
*/
public class Test
public static void main(String[] args)
/**
* 属性测试:测试枚举中的属性使用
*/
private static void propertyTest()
// 1.声明一个枚举对象,并赋值
Gender gender = Gender.MALE;
// 2.使用枚举对象去访问非静态属性
gender.description = "description";
System.out.println(gender.description);
// 3.访问静态 用类型去访问
Gender.count = 10;
枚举中的构造方法
// gender.java
public enum Gender
// 枚举里面的值通常都是大写的
MALE("男"),FEMALE("女"),UNKNOWN("未知");
// 这些枚举值其实是若干静态常量
// 相当于 public static final Gender MALE = new Gender("男");
// 相当于 public static final Gender FEMALE = new Gender("女");
// 相当于 public static final Gender UNKNOWN = new Gender("未知");
// 定义一个非静态属性
public String description;
// 定义了一个静态的属性
public static int count;
// 构造方法的测试
/**
* 枚举中的构造方法,默认的访问权限 都是私有的(private),并且,不能使用其他的权限修饰
*/
// Gender() // 无参构造
// System.out.println("一个枚举对象被实例化了");
//
Gender(String description) // 有参构造
this.description = description;
System.out.println("一个有参的构造方法被执行了");
Gender()
// Test.java
public class Test
public static void main(String[] args)
// Gender.count = 1;
constructorTest();
/**
* 属性测试:测试枚举中的属性使用
*/
private static void propertyTest()
// 1.声明一个枚举对象,并赋值
Gender gender = Gender.MALE;
// 2.使用枚举对象去访问非静态属性
gender.description = "description";
System.out.println(gender.description);
// 3.访问静态 用类型去访问
Gender.count = 10;
/**
* 构造方法的测试
*/
public static void constructorTest()
// 1.实例化一个枚举对象
Gender gender = Gender.MALE;
// 2.输出枚举对象的description属性值
System.out.println(gender.description);
枚举中的方法定义
// 枚举中的方法定义
public void show()
public String getDescription()
return description;
/**
* 枚举方法测试
*/
public static void methodTest()
// 1.获取一个枚举对象
Gender gender = Gender.MALE;
// 2.测试方法
String description = gender.getDescription();
System.out.println(description);
枚举中的方法重写
/**
* 方法重写的测试(Object、Interface接口)
*/
public static void overriderTest()
// 1.获取一个枚举对象
Gender gender = Gender.FEMALE;
// 2.直接输出gender
System.out.println(gender);
@Override
public String toString()
return description;
// 未重写toString的结果输出 一个有参的构造方法被执行了 一个有参的构造方法被执行了 一个有参的构造方法被执行了 FEMALE // 重写后的结果输出 一个有参的构造方法被执行了 一个有参的构造方法被执行了 一个有参的构造方法被执行了 女
枚举值
其实,所谓枚举中的值、元素,其实就是一个静态的、当前类的对象。
// 格式
public enum Gender
UNKNOWN
@Override
public String toString()
return ”未知“;
异常
概念:是对程序在运行过程中的种种不正常的情况的描述。
异常的本身是一个类
Exception
Java中的异常的继承体系
-
根类:Throwable
-
错误:Error
-
异常:Exception
-
以上是关于JavaEE入门级别最全教程2--初学者必看的主要内容,如果未能解决你的问题,请参考以下文章
-
-