文章目录
类的定义
类是对一个实体(对象)的描述,主要描述该实体(对象)的属性和功能。
如:洗衣机,可以将它看作一个类,具有的属性:品牌,颜色,尺寸等。
功能:洗衣服,甩干等功能。
类的定义格式
class Teather{
public String name;//属性
public int age;
public void fun(){//功能
System.out.println("正在授课");
}
public void eat(){
System.out.println("正在吃饭");
}
}
类的实例化
定义一个类相当于创建了一种新的类型又称为引用类型,与int float 相似如上我们定义了一个Teather类。
类名命名规则:采用大驼峰
那么我们如何实例化呢?看代码
public static void main(String[] args) {
Teather teather =new Teather();
}
实例化的意思是创建对象。
我们说过Teather类是我创建的新的类型,即引用类型,引用类型进行实例化就需要通过new关键字来实现。在堆上为这个对象开辟一块空间,而teacher这个对象保存堆上开辟空间的地址。那new Teacher()中”()“代表什么意思呢?,我们到后面的构造方法会讲解。
对象的引用
class Teather{
public String name;
public int age;
public void fun(){
System.out.println("正在授课");
}
public void eat(){
System.out.println("正在吃饭");
}
}
public class Student {
public static void main(String[] args) {
Teather teather = new Teather();
teather.eat();
teather.fun();
teather.name="张三";
System.out.println(teather.name);
}
}
通过对象.xxx 来实现属性的引用或方法的调用。
输出结果:
正在吃饭
正在授课
张三
小结
1.类是一个设计图,而对象是根据设计图,设计出来的房子🏠
2.类是一种自定义的一种类型
3.一个类可以实例出多个对象,实例出的对象占用实际空间。
4.类中的成员变量都有默认值如int是0,String是null。
构造方法
构造方法调用时机是当创建对象完成后调用。 Teather teather = new Teather();此条语句调用
❗️当没有写构造函数是编译器会默认提供一个无参的构造函数
🔴构造方法的名字必须与定义他的类名完全相同,没有返回值,返回类型也无。
🟠主要完成对象的初始化工作,构造方法的调用是在创建一个对象时使用new操作进行的
🟡类中必定有构造方法,若不写,系统自动添加无参构造方法。
🟢new对象时先创建对象后调用构造函数
class Teather{
public String name;
public int age;
Teather(String name1,int age1){
name=name1;
age=age1;
}
}
public class Student {
public static void main(String[] args) {
Teather teather = new Teather("钻石王老五",22);
System.out.println(teather.name+" "+teather.age);
}
}
这时是不是就知道()的作用了呢,就是给构造函数传参,实现成员变量初始化作用。
this引用
this作用是当参数名和类中的方法名同名时使用,this引用的是当前对象。
那个对象调用就是引用的那个对象。
class Teather{
public String name;
public int age;
Teather(String name,int age){
this.name=name;
this.age=age;
}
}
this()的应用
当类中你想调用两个构造函数时使用this()。,括号里可以传参,然后根据参数编译器去调用那个。
class Teather{
public String name;
public int age;
Teather(String name1,int age1){
this();//执行到此处调用另一个构造函数
name=name1;
age=age1;
}
Teather(){//即此处
name="哈哈";
}
}
public class Student {
public static void main(String[] args) {
Teather teather = new Teather("钻石王老五",22);
System.out.println(teather.name+" "+teather.age);
}
}
三大特性—封装📦
封装的意义:封装的意义就是为了不让类中的成员变量不能直接访问,起到数据保护作用。
1.保证数据安全性(封装可以为别人提供相应的功能,可不为别人显示相应的代码)
2.提供清晰的对外接口
3.类内部实现可以任意修改,不影响其他类(可复用性,灵活性,安全性,扩展性 )
访问修饰符
范围 | private | default | protected | public |
---|---|---|---|---|
同一个包中的同一类 | ✔️ | ✔️ | ✔️ | ✔️ |
同一包中的不同类 | ✔️ | ✔️ | ✔️ | |
不同包中的子类 | ✔️ | ✔️ | ||
不同包中的非子类 | ✔️ |
1.static关键字♨️
static被称为静态
static修饰的变量称为静态变量
static修饰的方法被称为静态方法
static修饰的变量又被称为类变量
static修饰的变量/方法不依赖于对象,随着类的加载而存在。
2.生命周期的区别
🟡1.静态变量随着类的加载而存在,随着类的销毁而销毁
🔴2.成员变量随着对象的创建而存在,随着对象的回收而释放
3.调用方法的区别
➡️成员变量可以通过对象.成员变量调用
➡️类变量可以通过类名.类变量调用,也可以对象.类变量调用
public class Person {
private int age;
private String name;
private static int size;
public static void fun1() {
;
}
public void fun2(){
System.out.println("很时尚");
}
public static void main(String[] args) {
Person person = new Person();
person.fun2();
person.fun1();
Person.fun1();//注意首字母是大写
}
}
4.存放的位置
🔺静态变量存放在方法区,静态变量和静态代码块只会调用一次其次具有资源共享的作用,注意点:因为共用一个,一个更改全部更改。比如:张三,李四,王五都在一个班里,我们直接使用static修饰
public class Person {
private int age;
private static String name;
private static int size;
static {
Person.name="79班";
}
public static void main(String[] args) {
Person person1 = new Person();
Person person2 = new Person();
Person person3 = new Person();
System.out.println(person1.name);
System.out.println(person2.name);
System.out.println(person3.name);
}
}
5.调用的区别
♦️在静态方法中,可以调用静态方法。
♦️在静态方法中,不能调用非静态方法。
♦️在静态方法中,可以引用类变量(static修饰的变量)。
♦️在静态方法中,不能引用成员变量(没有被static修饰的变量)。
🔸在普通方法中,可以调用普通方法。
🔸在普通方法中,可以调用静态方法
🔸在普通方法中,可以引用类变量和成员变量(但不能定义static定义的变量又称为类变量)
🔸在普通方法中,可以使用this关键字和super
当实例化两个或多个对象的时,静态变量/方法只调用一次,第二个之后将不再调用。
一、局部代码块
局部代码块应用于成员方法中,用于限制变量作用域问题。
二、 静态代码块
🔵静态代码块在类加载的时候执行,在main方法之前执行且只执行一次。
🟣静态代码块可以有多个,依据从前往后的顺序执行。
⚫️用于给静态成员变量初始化作用。
⚪️静态代码块执行次数与创建对象的个数没有关系,静态变量/方法不属于对象,静态的是共享的。
🟤静态代码块内部只能初始化静态成员变量,不能初始化实例变量,也不能使用this。
🔴在静态代码块中不能引用成员变量和成员方法,静态的可以。
注意若是a没初始化直接执行5️⃣位置
三、构造方法
🔴构造方法的名字必须与定义他的类名完全相同,没有返回值,返回类型也无。
🟠主要完成对象的初始化工作,构造方法的调用是在创建一个对象时使用new操作进行的
🟡类中必定有构造方法,若不写,系统自动添加无参构造方法。
🟢new对象时先创建对象后调用构造函数
四、实例代码块
🔺执行顺序:静态>实例>构造
🔸可以调用普通方法。
🔸可以调用静态方法
🔸可以引用类变量和成员变量(但不能定义static定义的变量又称为类变量)
🔸可以使用this关键字和super
三大特性—继承
现实世界错综复杂,事物之间可能存在一些关联,比如猫和狗都属于动物
继承机制:是面向对象设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生的类又称为派生类,共性的抽取,实现代码复用
继承只支持单继承,不支持多继承 。
修饰符 class 子类extends父类{
}
public class Animal{
public String name;
public int age;
public void eat(){
System.out.println(name+"吃饭");
}
Animal(String name,int age){
this.name=name;
this.age=age;
}
}
class Dog extends Animal{
Dog(String name,int age){
super(name,age);
}
}
class S{
public static void main(String[] args) {
Dog dog = new Dog("旺财",3);
dog.eat();
}
}
输出结果:旺财吃饭
子类继承了父类所以可以访问父类的成员变量和方法
成员方法名字相同
成员方法相同或不同时,优先访问子类,子类没有则访问父类
public class Animal{
public String name;
public int age;
public void eat(){
System.out.println(name+"吃饭");
}
Animal(String name,int age){
this.name=name;
this.age=age;
}
}
class Dog extends Animal{
public void eat(){
System.out.println(" hahah");
}
Dog(String name,int age){
super(name,age);
}
}
class S{
public static void main(String[] args) {
Dog dog = new Dog("旺财",3);
dog.eat();
}
}
输出结果:hahah
super关键字
super关键字的主要作用:在子类方法中访问父类的成员,当父类成员和子类成员名字相同时,用于区别。
public class Animal{
public String name;
public int age;
public void eat(){
System.out.println(name+"吃饭");
}
Animal(String name,int age){
this.name=name;
this.age=age;
}
}
class Dog extends Animal{
public String name;
public void eat(){
super.name="啦啦";
System.out.println(name+""+super.name);
}
Dog(String name,int age){
super(name,age);
}
}
class S{
public static void main(String[] args) {
Dog dog = new Dog("旺财",3);
dog.eat();
}
}
输出结果:null啦啦
super和this区别
相同点:
🌳都是java关键字
🌳只能在非静态方法中使用,用来访问非静态成员变量和方法
🌳在构造方法中必须是第一条语句,不能同时出现
不同点:
🎄this是当前对象的引用,super相当于子类从父类继承下来的部分成员的引用
🎄在非静态成员方法中this用来访问对象中的成员,super用来访问父类继承下来的属性和方法
🎄在构造方法中this(…)用来调用本类其他的构造方法,super(…)用来调用父类的构造方法,两种调用不能同时出现在构造函数中。
🎄在构造方法中一定会有super(…),但是this(…)用户不写则没有
继承关系上的 执行顺序
public class Animal{
static{
System.out.println("Animal静态");
}
{
System.out.println("Animal实例代码块");
}
Animal(){
System.out.println("父类构造函数");
}
}
class Dog extends Animal{
static{
System.out.println("Dog静态");
}
Dog(){
System.out.println("子类构造函数");
}
{
System.out.println("Dog代码块");
}
}
class Ss{
public static void main(String[] args) {
Dog dog = new Dog();
}
}
运行结果:
Animal静态
Dog静态
Animal实例代码块
父类构造函数
Dog代码块
子类构造函数
final关键字
被final关键字修饰的类不能被继承!
final public class Student{
....
}
三大特性—多态
多态的概念:主要是完成一个行为,当不同的传参产生不同的状态
多态产生的条件:
必须在继承下
子类必须要对父类方法进行重写
通过父类的引用调用重写方法
public class Animal{
public String name;
public void eat(){
;
}
Animal(String name){
this.name=name;
}
}
class Dog extends Animal{
public void eat(){
System.out.println(super.name+"吃骨头");
}
Dog(String name){
super(name);
}
}
class Cat extends Animal{
public void eat (){
System.out.println(super.name+"正在吃鱼");
}
Cat(String name){
super(name);
}
}
class Ss{
public static void main(String[] args) {
Dog dog = new Dog("旺财");
Cat cat = new Cat("小七");
dog.eat();
cat.eat();
}
}
运行结果:
旺财吃骨头
小七正在吃鱼
重写
重写是对非静态,非private修饰,非final修饰,非构造方法等方法进行重新编写,返回值、参数不得改变,即外壳不变,核心重写。
【方法重写规则】
◼️当子类重写父类的方法时,一般必须与父类方法原型一致,返回值类型、方法名、(参数列表)要完全一致
◼️被重写的方法返回值类型可以不同,但是必须具有父子关系。
◼️访问修饰权限不能比父类修饰权限低
◼️重写的方法,可以使用@Override注解来显式指定,有了这个注解能够帮我们进行合法检验
public class Animal{
public String name;
public void eat(){
;
}
Animal(String name){
this.name=name;
}
}
class Dog extends Animal{
public void eat(){
System.out.println(super.name+"吃骨头");
}
Dog(String name){
super(name);
}
}
class Cat extends Animal{
public void eat (){
System.out.println(super.name+"正在吃鱼");
}
Cat(String name){
super(name);
}
}
如⬆️代码我们能看出父类有eat方法,我们又在子类中去重新编写了eat方法这就叫重写。
重载和重写的区别
区别点 | 重写 | 重载 |
---|---|---|
参数列表 | 一定不能修改 | 必须修改 |
返回类型 | 不能修改,除非具有父子关系 | 可以修改 |
访问修饰操作符 | 一定不能做更严重的限制 | 可以修改 |
静态绑定
在编译时就已确定好调用哪个方法。
动态绑定
编译时不能确定调用哪个方法,等运行时才能确定调用哪个方法
向上转型
向上转型就是创建一个子类对象,当父类使用。
语法格式:父类 对象名=new 子类类型();
向上转型的目的:调用子类的重写方法
public class Animal{
public String name;
public void eat(){
;
}
Animal(String name){
this.name=name;
}
}
class Dog extends Animal{
public void eat(){
System.out.println(super.name+"吃骨头");
}
Dog(String name){
super(name);
}
}
class Cat extends Animal{
public void eat (){
System.out.println(super.name+"正在吃鱼");
}
Cat(String name){
super(name);
}
}
class Ss{
public static void main(String[] args) {
Animal dog = new Dog("旺财");
Animal cat = new Cat("小七");
dog.eat();
cat.eat();
}
}
向下转型
向下转型:先实现向上转型才能实现向下转型。
向下转型目的:调用子类中的特有方法。
public class Animal{
public String name;
public void eat(){
;
}
Animal(String name){
this.name=name;
}
}
class Dog extends Animal{
public void eat(){
System.out.println(super.name+"吃骨头");
}
Dog(String name){
super(name);
}
public void run(){
System.out.println(super.name+"正在跑");
}
}
class Ss{
public static void main(String[] args) {
Dog dog=new Dog("十七");
Animal animal=dog;
dog=(Dog)animal;
dog.run();
}
}
避免在构造方法中调用重写方法否则将会发生动态绑定。