构造方法 -- 又名构造器 、 构造函数
*
* 1.构造方法的语法: 修饰符 类名(参数列表){方法体}
* 2.用处:专门用来创建对象的
* 3.什么时候触发? new时/实例化时
* 4.无参构造是默认就存在的,但是如果只提供了有参构造,
* 默认的无参构造就没有了,最好手动提供无参构造
package test.day02;
/*
* 构造方法 -- 又名构造器 、 构造函数
*
* 1.构造方法的语法: 修饰符 类名(参数列表){方法体}
* 2.用处:专门用来创建对象的
* 3.什么时候触发? new时/实例化时
* 4.无参构造是默认就存在的,但是如果只提供了有参构造,
* 默认的无参构造就没有了,最好手动提供无参构造
*
* 给成员变量赋值的方法 set() + 构造方法
* 没有返回值类型 与类同名
* 可以实现重载
* 创建对象的时候会自动调用构造方法,new的对象有参数 调用有参数的
* new的对象无参数 调用无参数的
* 构造方法不能被手动调用,只能创建对象时自动被调用
*
*/
public class Test1_Constructor {
public static void main(String[] args) {
Person p1 = new Person();// 自动调用无参的构造方法
Person p2 = new Person("海绵宝宝");// 自动调用String类型的有参构造
// 只要 new 就可以调用构造方法 和对象名无关;
new Person(5);// 自动调用 int 类型的有参构造
new Person("派大星",1);// 自动调用String、int类型的有参构造
}
}
class Person{
private String name;
/*
* 类中默认提供一个隐藏的无参构造方法。
* 当类中提供了有参构造时,类中默认的隐藏的无参构造就没有了。
* 这是可以自己定义一个无参构造,调用时使用自己定义的无参构造
*/
// 无参的
public Person() {
System.out.println("没有参数的构造方法");
}
// 有参数的
// 重载形式的构造方法
public Person(String s) {
// 利用构造方法给成员变量name赋值
name = s;
System.out.println("有参数的构造方法" + s + name);
}
public Person(int a) {
System.out.println("这是写的第一个有参构造" + a);
}
public Person(String a, int b) {
System.out.println("这是写的第二个有参构造" +a+ b);
}
}
代码块
/*
* 1.构造代码块: 位置:类中方法外作用:提取构造方法的共性触发点:new时
* 2.局部代码块:位置:方法里作用:控制变量的作用范围触发点:调用方法时
* 3.执行顺序: 构造代码块 > 构造方法 > 局部代码块
* 4.创建对象时发生了几件事?
* 先执行构造代码块,再执行构造方法
// 代码块
/*
* 1.构造代码块: 位置:类中方法外 作用:提取构造方法的共性 触发点:new时
* 2.局部代码块:位置:方法里 作用:控制变量的作用范围 触发点:调用方法时
* 3.执行顺序: 构造代码块 > 构造方法 > 局部代码块
* 4.创建对象时发生了几件事?
* 先执行构造代码块,再执行构造方法
*/
public class Test2_Block {
public static void main(String[] args) {
new Teacher();
new Teacher("中国");
new Teacher(666).show();
}
}
class Teacher{
int age;
/*
* 1. 构造代码块 - 在类里方法外,和构造方法并列
* 在执行构造方法之前执行代码块
* 触发点:每次new的时候都执行
* 作用:通常用于抽取构造方法中的共性代码
*/
{
age = 10;
System.out.println("这是构造代码块");
System.out.println(1);
}
{
System.out.println(2);
}
public Teacher() {
System.out.println("无参构造" + age);
}
public Teacher(String a) {
System.out.println("有参构造 " + a);
}
public Teacher (int a) {
System.out.println("有参构造 " + a);
}
/*
* 2.局部代码块 -- 在方法里
* 作用:用来控制变量的作用范围
* 触发点:方法被调用时执行
*/
public void show() {
{
int a = 9;
System.out.println(a);
System.out.println("这是局部代码块");
}
// System.out.println( a); // 报错
}
}
this 关键字
/* 1.在本类中,访问本类的成员变量和成员方法,都可以用this
* 只不过大部分情况都可以省略,
* 2.但是当局部变量和成员变量同名时,必须使用this来调用成员变量
1.this代表本类的一个引用,相当于底层帮助创建了本类的对象,
* 例如:Student this = new Student();
* 2.this可以调用本类的成员,包括成员变量和成员方法
* 3.由于成员变量和局部变量都叫a,根据就近原则优先使用局部变量,
* 若想先用同名的成员变量,必须用this
this关键字
*
* 1.构造方法间 想要相互调用,可以使用this([参数])
* 2.this()如果出现在构造方法中,必须放在第一行!
// this 关键字
/* 1.在本类中,访问本类的成员变量和成员方法,都可以用this
* 只不过大部分情况都可以省略,
* 2.但是当局部变量和成员变量同名时,必须使用this来调用成员变量
*/
public class Test3_This {
public static void main(String[] args) {
Student s = new Student();
s.test();
}
}
class Student{
private String name;
public void setName(String name) {
/*
* 只能在本类中可以使用
* 当成员变量和局部变量重名时使用
* this作用:this调用本类的成员变量并赋值
*/
this.name = name;
}
int a = 10; // 成员变量
public void test() {
int a = 20; // 局部变量
System.out.println(a);//变量使用的就近原则,使用了局部变量
/*
* 1.this代表本类的一个引用,相当于底层帮助创建了本类的对象,
* 例如:Student this = new Student();
* 2.this可以调用本类的成员,包括成员变量和成员方法
* 3.由于成员变量和局部变量都叫a,根据就近原则优先使用局部变量,
* 若想先用同名的成员变量,必须用this
*/
System.out.println(this.a); // 使用成员变量
System.out.println(this); // com.huacit.day02.Student@15db9742
this.setName("lisa"); // 使用成员方法
System.out.println(name);
}
}
/*
* this关键字
*
* 1.构造方法间 想要相互调用,可以使用this([参数])
* 2.this()如果出现在构造方法中,必须放在第一行!
*/
public class Test4_This2 {
public static void main(String[] args) {
new Demo();
// new Demo(4);
}
}
class Demo{
public Demo() {
// 3.在无参构造里调用有参构造
this(5);
System.out.println("无参构造方法");
}
public Demo(int a) {
// 1.在有参构造方法里调用无参构造方法
// 2.this(); 必须放在构造方法的第一行
// this();
System.out.println("有参构造方法 " + a);
}
}
* 面试题:java中一个类可不可以继承多个父类?
* 不可以,java只支持单继承
父类 作用:通常用来提取子类的共性,提高了代码的复用性
当父类里的私有资源,子类是不能继承的
子类 可以继承父类来使用父类的功能,使用extends关键字表示继承关系
java只支持单继承 一个类只能继承一个父类
相当于子类把父类的功能复制了一份
继承具有传递性
// 继承
/*
* 面试题:java中一个类可不可以继承多个父类?
* 不可以,java只支持单继承
*/
public class Test5_Extends {
public static void main(String[] args) {
Dog d = new Dog();
d.eat();
}
}
// 1.父类 作用:通常用来提取子类的共性,提高了代码的复用性
class Animal{
// 当父类里的私有资源,子类是不能继承的
private String name;
public void eat() {
System.out.println("吃饭");
}
}
// 2.子类 可以继承父类来使用父类的功能,使用extends关键字表示继承关系
// java只支持单继承 一个类只能继承一个父类
class Dog extends Animal{
// 相当于子类把父类的功能复制了一份
}
class Cat extends Animal{
}
class Linon extends Animal{
}
public class Test6_Extends2 {
public static void main(String[] args) {
// 创建子类对象测试
Son s = new Son();
// 子类可以使用父类的功能
s.eat();
// 子类也可以使用爷爷类的功能 -- 继承具有传递性
System.out.println(s.name);
}
}
class GFather{
String name;
}
class Father extends GFather{
public void eat() {
System.out.println("吃饭");
}
}
class Son extends Father{
}
// super关键字
/*
* 1.当发生继承关系后,在子类中想用父类的功能或属性,通过super关键字实现
* 如果 不同名时 ,super 可以省略
* 2.如果父类和子类有同名的成员变量,必须使用super调用父类的,
* 否则优先使用子类自己的
* 1.当子类的成员变量名与父类的成员变量名相同时,
* 通过super关键字来调用父类的成员变量。
* 相当于 super在底层帮助下创建了父类对象
* 如:Fu super = new Fu();
* 2.super 表示父类对象的引用,用来在子类中调用父类的成员
super关键字 -- 调用父类的构造方法
/*
* 1.创建子类对象时,父类对象有没有?
* -- 有,先有的父类对象,再有子类对象
* 2.触发构造方法时,什么顺序?
* -- 先执行父类的,再执行子类的
* 3.为什么先执行父类的构造方法?
* -- 因为 子类的构造方法里,默认第一行隐藏着super()
// 一个构造方法里 只能有一个super()
// 1. 在子类的构造方法中,隐藏着super(),super()调用父类的无参构造方法
2.创建子类对象时,先触发父类的无参构造,再触发子类的构造方法
3.super() 如果出现在构造方法里,必须放在第一行!
4.当父类中只提供了有参构造,默认的无参构造就没有了,
* super()就找不到无参构造方法,就会报错
5.当父类没有无参构造时,只能调用父类的有参构造
// super关键字
/*
* 1.当发生继承关系后,在子类中想用父类的功能或属性,通过super关键字实现
* 如果 不同名时 ,super 可以省略
* 2.如果父类和子类有同名的成员变量,必须使用super调用父类的,
* 否则优先使用子类自己的
*/
public class Test7_Super {
public static void main(String[] args) {
Zi z = new Zi();
z.test();
}
}
class Fu{
int a = 10;
String name = "波风水门";
}
class Zi extends Fu{
String name = "漩涡鸣人";
public void test() {
System.out.println(a);// 10 使用了父类的变量(不同名,可以直接使用)
System.out.println(name);// 漩涡鸣人 使用了子类的成员变量
/*
* 1.当子类的成员变量名与父类的成员变量名相同时,
* 通过super关键字来调用父类的成员变量。
* 相当于 super在底层帮助下创建了父类对象
* 如:Fu super = new Fu();
* 2.super 表示父类对象的引用,用来在子类中调用父类的成员
*/
System.out.println(super.name);// 波风水门 使用了父类的name
}
}
// super关键字 -- 调用父类的构造方法
/*
* 1.创建子类对象时,父类对象有没有?
* -- 有,先有的父类对象,再有子类对象
* 2.触发构造方法时,什么顺序?
* -- 先执行父类的,再执行子类的
* 3.为什么先执行父类的构造方法?
* -- 因为 子类的构造方法里,默认第一行隐藏着super()
*/
/*
* 面试题:this和super的区别?
* this 指代的当前类的对象,可以使用this调用当前类的成员变量或成员方法
* this()可以调用本类的构造方法,必须放在构造方法第一行!
* super 指代的是父类的对象,可以使用super调用父类的成员变量或成员方法,
* super()可以调用父类的构造方法,必须放在构造方法第一行!
*
* 面试题:this()和super()能不能同时出现在同一个构造方法中?
* --不能,this()和super()都必须放在构造方法的第一行。
*
*/
// 一个构造方法里 只能有一个super()
public class Test8_Super2 {
public static void main(String[] args) {
// 2.创建子类对象时,先触发父类的无参构造,再触发子类的构造方法
new Zi2();
}
}
class Fu2{
// public Fu2() {
// System.out.println("父类的无参构造");
// }
public Fu2(int a) {
System.out.println("父类的有参构造" + a);
}
}
class Zi2 extends Fu2{
public Zi2() {
// 1. 在子类的构造方法中,隐藏着super(),super()调用父类的无参构造方法
// 3.super() 如果出现在构造方法里,必须放在第一行!
/*
* 4.当父类中只提供了有参构造,默认的无参构造就没有了,
* super()就找不到无参构造方法,就会报错
*/
// super();
/*
* 5.当父类没有无参构造时,只能调用父类的有参构造
*/
super(5);
System.out.println("子类的构造方法");
}
}
面试题:this和super的区别?
* this 指代的当前类的对象,可以使用this调用当前类的成员变量或成员方法
* this()可以调用本类的构造方法,必须放在构造方法第一行!
* super 指代的是父类的对象,可以使用super调用父类的成员变量或成员方法,
* super()可以调用父类的构造方法,必须放在构造方法第一行!
*
* 面试题:this()和super()能不能同时出现在同一个构造方法中?
* --不能,this()和super()都必须放在构造方法的第一行。
面试题:this和super的区别?
* this 指代的当前类的对象,可以使用this调用当前类的成员变量或成员方法
* this()可以调用本类的构造方法,必须放在构造方法第一行!
* super 指代的是父类的对象,可以使用super调用父类的成员变量或成员方法,
* super()可以调用父类的构造方法,必须放在构造方法第一行!
*
* 面试题:this()和super()能不能同时出现在同一个构造方法中?
* --不能,this()和super()都必须放在构造方法的第一行。
重写 override
/*
* 1.子类可以使用父类的所有功能(私有的除外)
* 2.子类还可以扩展自己的方法
* 3.子类可以重写从父类继承来的方法
* 4.什么时候会发生重写? -- 子类继承父类后,子类想要修改父类的功能
* 5.重写有什么要求?
* (1).子类的方法声明(指方法名和参数列表)和父类一样,
* (2).返回值类型在JDK1.5之前必须一样,JDK1.5之后,
* 返回值类型必须小于或等于父类方法的返回值类型
* 如果是八种基本数据类型或void,则必须保持一致,
* 如果是引用类型,重写前返回值类型为父类的类型,
* 重写后可以返回其子类的类型
* (3).访问权限大于或等于父类的访问权限
* (4).抛出的异常不能大于父类抛出的异常类型
* 6.在开发过程中,避免修改源代码
* 提高程序的扩展性,可以继承后重写,这时候把子类的功能修改了,
* 但是并没有对源码的功能产生影响
*/
//
面试题:重写(Override)和重载(Overload)的区别?
/*答:重载发生在同一个类中,方法名相同,参数列表不同,
* 与返回值类型无关
*
* 重写发生在父子类之间,方法名相同,参数列表相同
* 返回值类型如果是八种基本数据类型或void时相同,
* 如果是引用类型可以小于等于父类的返回值类型
* 访问权限大于等于父类
* 抛出异常小于等于父类
当继承了父类的所有方法之后,发现想改 -- 方法重写的现象
*
* 方法重写的语法要求:
* 1.子类的方法声明(指方法名和参数列表)和父类一样,
* 2.返回值类型在JDK1.5之前必须一样,JDK1.5之后,
* 返回值类型必须小于或等于父类方法的返回值类型
* 如果是八种基本数据类型或void,则必须保持一致,
* 如果是引用类型,重写前返回值类型为父类的类型,
* 重写后可以返回其子类的类型
* 3.访问权限大于或等于父类的访问权限
// 重写 override
/*
* 1.子类可以使用父类的所有功能(私有的除外)
* 2.子类还可以扩展自己的方法
* 3.子类可以重写从父类继承来的方法
* 4.什么时候会发生重写? -- 子类继承父类后,子类想要修改父类的功能
* 5.重写有什么要求?
* (1).子类的方法声明(指方法名和参数列表)和父类一样,
* (2).返回值类型在JDK1.5之前必须一样,JDK1.5之后,
* 返回值类型必须小于或等于父类方法的返回值类型
* 如果是八种基本数据类型或void,则必须保持一致,
* 如果是引用类型,重写前返回值类型为父类的类型,
* 重写后可以返回其子类的类型
* (3).访问权限大于或等于父类的访问权限
* (4).抛出的异常不能大于父类抛出的异常类型
* 6.在开发过程中,避免修改源代码
* 提高程序的扩展性,可以继承后重写,这时候把子类的功能修改了,
* 但是并没有对源码的功能产生影响
*/
// 面试题:重写(Override)和重载(Overload)的区别?
/*答:重载发生在同一个类中,方法名相同,参数列表不同,
* 与返回值类型无关
*
* 重写发生在父子类之间,方法名相同,参数列表相同
* 返回值类型如果是八种基本数据类型或void时相同,
* 如果是引用类型可以小于等于父类的返回值类型
* 访问权限大于等于父类
* 抛出异常小于等于父类
*
*/
public class Test9_Override {
public static void main(String[] args) {
// 创建了子类对象测试
Zi3 z = new Zi3();
// 使用了父类的方法
z.eat();// 重写前
z.sleep();
// 使用自己特有的扩展方法
z.coding();
z.play();
}
}
// 1. 父类的方法可以被子类继承
// 一个父类可以有很多个子类,但是一个子类只能有一个父类
class Fu3{
public Fu3() {
}
public Fu3 eat() {
System.out.println("Fu...eat()");
return new Fu3();
}
public void sleep() {
System.out.println("Fu...sleep()");
}
public Fu3 fnn() { // 重写前 返回值类型是Fu3
return new Fu3();
}
}
// 2. 子类还可以扩展自己的方法
class Zi3 extends Fu3{
// public Fu3() {
//
// }
public Zi3() {
}
/*
* 当继承了父类的所有方法之后,发现想改 -- 方法重写的现象
*
* 方法重写的语法要求:
* 1.子类的方法声明(指方法名和参数列表)和父类一样,
* 2.返回值类型在JDK1.5之前必须一样,JDK1.5之后,
* 返回值类型必须小于或等于父类方法的返回值类型
* 如果是八种基本数据类型或void,则必须保持一致,
* 如果是引用类型,重写前返回值类型为父类的类型,
* 重写后可以返回其子类的类型
* 3.访问权限大于或等于父类的访问权限
* 4.抛出的异常不能大于父类抛出的异常类型
*/
@Override // 标志着这个方法是重写方法
public Zi3 eat() {
super.eat();// 5.对于父类原有的功能没有任何影响
System.out.println("Zi...吃肉");
return new Zi3();
}
public void play() {
System.out.println("Zi...play()");
}
public void coding() {
System.out.println("Zi...coding()");
}
// 重写后,返回值类型可以为Fu3,也可以是Fu3的子类型 -Zi3
// public Fu3 fnn() {
// return new Fu3();
// }
public Zi3 fnn() {
super.fnn();
return new Zi3();
}
}