后续的各种用法都是在创建好类的基础上去使用的
1、类中常见的其他用法
1.1this关键字
this的作用:表示当前对象,指向调用对象
this调用属性,可以在普通方法中调用,也可以在构造方法中调用
在普通方法中使用this,一般是局部变量和成员变量同名,通过this指向成员变量
普通方法中的this,指向调用者,哪个对象调用方法,就指向哪个对象
构造方法中的 this,指向 new 出来的对象,new 出来的是哪个对象,就指向哪个对象
this 用来调用方法 ,在类中的成员方法中,可以通过 this 调用其他的成员方法,可以省略 this
this 用来调用构造方法 ,在当前构造方法中,可以调用其他构造方法,写法:this(参数),参数传的值决定了你调用的是哪个构造方法
①this调用属性局部变量和成员变量同名的话,必须加上this来区分,加上this后的变量指向成员变量
②this调用方法,this可加可不加
③this调用构造方法不能调用自身;
this(),this后面直接写括号的写法,表示调用类中的其他构造方法;
this后面括号中的参数类型,就表示调用构造方法的是哪个;
this调用构造方法,this语句必须在第一行
----第三种方法(搭配使用) public Person(){ this("jack"); } public Person(String name){ this.name=name; }----第二种方法(搭配使用) public void setName(String name){ this.name=name; } public String getName(){ return this.name; }1.2封装
Java 中的封装,是一种隐藏技术,可以把程序的设计者和使用者分开,使用者不必知道程序设计的细节,直接使用就行,也可以增加代码的安全性
实现封装的方式:通过private关键字实现
①private和public都是修饰符,直接把public换成private就可以了
②private可以用在属性、构造方法、成员方法的前面(一般来说构造方法不加private,普通方法前面不加private)
public class Student { //给属性加上private private String name; private int age; private String gender; private Student(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } private void show(){ } }private使用特点:
1,使用 private 以后,在其他类中无法直接调用被 private 修饰的属性、方法
2,一般情况下,一个类中,属性需要加上private, 构造方法和普通方法根据需求决定是否加上 private
3,属性私有化以后,在其他类中,不能直接通过 .点 的方式赋值 或者 获取值,可以在类中创建set/get 方法,通过 set 方法赋值 ,通过 get 方法获取值(一次性可以获取一个值)
私有化的属性,可以有 2 种方式赋值,set 方法 和全参构造
只有 1 种方法获取值 ,get 方法
public class Student { //给属性加上private private String name; private int age; private String gender; public Student(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } public Student() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public void show(){ System.out.println("我的姓名是"+name+"我的年龄是"+age+"我的性别是"+gender); } }public class Text { public static void main(String[] args) { Student s1=new Student("张三",24,"男"); s1.show(); System.out.println(s1.getName()); Student s2=new Student(); //set方法赋值 s2.setName("木木"); s2.show(); //get方法获取值 System.out.println(s2.getName()); } }1.3访问修饰符
public 公共的,公开的 可以在任意的位置访问 public 修饰的内容
private 私有化的 只能在当前类中使用,其他类中用不了
default 默认的 属性前面不写任何修饰符 就是默认的 ,同一个包下的不同类中可以访问
protected 受保护的 同一个包下类或者不同包下的子类可以访问
1.4继承extends
继承的概念:
把多个具有相同属性的类,抽取其中的属性,放入到另一个公共的类A中,让被抽取的类和这个类A产生一个关系,所有被抽取的类也具有了这个类A的所有公共的属性和方法,这种关系就称为继承,被继承的类称为父类、超类、基类,继承的类称为子类
继承的写法:
使用entends关键字实现
class B entends A{ }
继承的好处:提升了代码的复用性,让类和类之间产生关系,是多态的前提
继承的坏处:增加了类和类之间的耦合性(关联性)
继承的特点:
①继承的时候,子类可以继承父类非私有的属性、方法,不能直接继承父类私有的属性,但是可以间接的使用 , 可以通过继承父类的 set 方法完成属性的赋值,通过继承父类的 get 方法完成属性值获取。
②继承的时候,子类不能继承父类的构造方法,但是可以通过 super 关键字去访问父类的无参或者有参构造,如果希望通过有参构造创建子类对象,那么就可以通过super访问父类的有参构造
③继承的时候,如果没有显式的继承某个类,系统会自动让类去继承 Object 类,Object 类是所有类的父类,也称为始祖类
④继承只能单继承,不能一次性继承多个类,但是可以多重继承
public class Person { String name; int age; String gender; public void show(){ System.out.println("我的姓名是:"+name+",我的年龄是:"+age+",我的性别是:"+gender); } }public class Student extends Person { }public class Text { public static void main(String[] args) { Person p=new Person(); p.name="张三"; p.age=18; p.gender="男"; p.show(); Student s=new Student(); s.name="李四"; s.age=19; s.gender="男"; s.show(); } }1.5 继承中super的使用(用super继承父类的构造方法——无参、有参)
super关键字的用法
①super 关键字表示父类对象,只能用在子类中,用来调用父类非私有的属性、方法、构造方法
②super 调用属性使用的情况非常少见,因为大部分的类属性都会加上 private,super 无法调用 private 属性
③super 调用父类的方法,一般子类存在和父类同名方法的时候,可以通过 super 区分调用的是父类的方法还是子类的方法
super 调用父类的构造方法
①所有的子类构造方法,都会访问父类的构造方法,默认是访问无参构造
②将来我们可以通过在子类中编写super(参数)调用父类的有参构造,让子类访问父类的有参构造
③将来编写父类的时候尽量把无参构造加上,如果父类没有无参构造,子类必须通过super访问父
类的有参构造
④super 调用构造方法的写法是 :super()
括号中传入参数的类型,表示调用父类的哪个有参构造
⑤super()在子类调用父类构造方法的时候,必须写在子类构造方法的第一行,不能和 this() 调用构
造方法的写法同时出现
public class Person { private String name; private int age; private String gender; public Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } public void show(){ System.out.println("我的姓名是:"+name+",我的年龄是:"+age+",我的性别是:"+gender); } }public class Teacher extends Person { public Teacher(String name, int age, String gender) { super(name, age, gender); } public Teacher() { } }public class Text { public static void main(String[] args) { Teacher t=new Teacher("木木",22,"女"); t.show(); } }1.6子类有自己的属性
子类有自己的属性时,使用super继承父类构造方法之后还要在继承来的构造中加上子类自己的属性,以及set、get方法
public class Teacher extends Person { private String cname; public Teacher() { } public Teacher(String name, int age, String gender,String cname) { super(name, age, gender); this.cname=cname; } public String getcname() { return cname; } public void setcname(String cname) { this.cname= cname; } public void show(){ System.out.println("我的姓名:" + getName()+"我的年龄:"+getAge()+"我的性别"+getGender()+ "我教授的课程"+cname); } }1.7方法重写
子类默认可以继承父类的公共的方法,但是有的时候,父类方法功能不是子类想要的 ,那么子类就可以重新编写父类的方法,这个动作就是重写方法。
方法重写 :
在继承关系中,子类重写父类的方法,方法名相同、参数列表相同、返回值类型相同或者是父类方法返回值类型的子类,访问修饰符不能严于父类,不能比父类抛出更多的异常。
@Override :方法重写的检查注解,如果不符合重写规则,提示错误
第一段代码和第二段代码对比观察
package com.day8.test4; public class Father { public void method(){ System.out.println("这是父类的普通方法"); } public Father method1(){ System.out.println("这是父类的普通方法"); return new Father(); } public void method2(int a,int b){ System.out.println(a + b); } public void method3(){ System.out.println("父类的普通方法"); } }package com.day8.test4; public class Son extends Father{ @Override public void method() { System.out.println("子类重写方法"); } //返回值类型是父类方法返回值的子类 public Son method1(){ return new Son(); } //@Override //参数类型不一样,不是重写 public void method2(String a,String b){ System.out.println(a + b); } // @Override //修饰符不能严于父类 // private void method3() { // // } }方法重写的应用,重写equals方法
package com.day8.test4; import java.util.Objects; public class Student { int sid; String name ; String className; public Student() { } public Student(int sid, String name, String className) { this.sid = sid; this.name = name; this.className = className; } @Override public final boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Student student)) return false; return sid == student.sid && Objects.equals(name, student.name) && Objects.equals(className, student.className); } @Override public int hashCode() { int result = sid; result = 31 * result + Objects.hashCode(name); result = 31 * result + Objects.hashCode(className); return result; } }