一.代码块
1.代码块分类
1).局部代码块
书写位置:方法中
作用:限制变量的作用域
2)构造代码块
书写位置:类中方法外
作用:当创建每一个对象时,执行某些方法可以在构造代码块中调用(利用创建对象就会执行构造代码块)
调用:系统调用(创建对象时自动调用)在构造方法之前被调用
3)静态代码块
书写位置:类中方法外,使用static修饰的代码块
调用:
随着类的加载而调用与对象无关
只加载一次
加载类到方法区时系统自动调用
作用:加载驱动程序
4)同步代码块
public class Day07{
static {
System.out.println("我是Day07里的静态代码块");
}
public static void main(String[] args) {
{
System.out.println("局部代码块");
}
Person person = new Person();//系统调用无参的构造方法
}
}
class Person{
String name;
public Person() {
System.out.println("无参数构造");
}
public Person(String name) {
this.name = name;
System.out.println("有参数构造");
}
public void satHi() {
System.out.println(name);
}
//构造代码块
{
System.out.println("构造代码块");
}
//静态代码块
static {
System.out.println("静态代码块");
}
}
2.代码块练习
public class Day06 {
{
System.out.println("我是Day06的静态代码块");
}
public static void main(String[] args) {
System.out.println("main方法");
Test t1 = new Test();
Test t2 = new Test();
System.out.println("哈哈");
Test t3 = t2;
}
}
class Test{
String name;
public Test() {
System.out.println("我是Test类的无参构造方法");
}
public Test(String name) {
System.out.println("我是Test类的有参构造方法");
}
{
System.out.println("我是Test类的构造代码块");
}
static {
System.out.println("我是Test类的静态代码块");
}
}
//输出结果:
{
我是Day06的静态代码块
main方法
我是Test类的静态代码块
我是Test类的构造代码块
我是Test类的无参构造方法
我是Test类的构造代码块
我是Test类的无参构造方法
}
二.继承
1.继承的特点
1)继承链
2)继承具有传递性
3)继承属性和行为
4)建立类与类之间的关系
2.继承的好处和弊端
好处:
1).减少代码量
2提高工作效率
3).增强代码的复用性
弊端:
1).高内聚:指一个类的内部方法的联系程度
2).低耦合:类与类之间尽量减少联系
3.结构:
关键词 extends
子类 extends 父类
判断能否使用继承的方法:
子类 是 父类 是否符合逻辑
/*
* 动物类
* 姓名 年龄
* 猫类
* 姓名 年龄 喵喵
*
* 狗类
* 姓名 年龄 汪汪
*/
//父类
class Animal{
String name;
int age;
public void sayHi() {
System.out.println(name +" "+ age);
}
}
//猫类
class Cat extends Animal{
public void speak() {
System.out.println("喵喵");
}
}
//狗类
class Dog extends Animal{
public void speak() {
System.out.println("汪汪");
}
}
3.Java是单继承
Java中的继承是类与类之间的继承,只允许单继承,多继承体现在借口呢方面
Java中允许多层继承(继承链)A->B->C
public class Day07 {
public static void main(String[] args) {
DemoA a = new DemoA();
//直接打印对象实际是调用了Object中的toString方法
System.out.println(a);
}
}
class DemoA{
String name;
//java中所有的类如果没有写继承哪个类,默认继承Object类
//父类
public void sayHi() {
System.out.println(name);
}
}
子类
class DemoB extends DemoA{
}
子类
class DemoC extends DemoB{
}
4.继承中的构造方法
注意:构造方法不能被继承
public class Day07 {
public static void main(String[] args) {
Son s1 = new Son();
//为什么会调用父类无参数构造方法?
//保证继承的完整性
//创建子类对象时为了保证继承的完整性,会默认调用父类无参数构造方法
Son s2 = new Son("李四");//调用父类无参数构造方法
}
}
class Father{
String name;
//无参数
public Father() {
super();//表示father的父类Object对象
System.out.println("father无参数构造方法");
}
public Father(String name) {
this.name = name;
System.out.println("father无参数构造方法");
}
public void sayHi() {
System.out.println(name);
}
}
class Son extends Father{
public Son() {
//系统会在子类的无参数构造方法的第一行写入super()调用父类的无参构造方法
super();//super调用父类的无参构造方法
System.out.println("son类无参数构造方法");
}
public Son(String name) {
super();
this.name = name;
System.out.println("son类无参数构造方法");
}
}
4.1如果父类中没有提供无参数的构造方法
如果父类中没有提供无参数的构造方法说明该类中会有一个有参数的构造方法,可以调用有参数的构造方法来保证继承的完整性
Javabean规范:
1.成员变量私有化
2.提供set/get方法
3.必须提供无参数的构造方法
注意:写代码至少写一个无参数的构造方法,最好无参数有参数都写
class D1{
String name;
public D1(String name) {
System.out.println("我是D1有参数构造方法");
}
}
class D2 extends D1{
//可以在构造方法的第一行调用有参数的构造方法保证继承的完整性
//只要在子类中调用父类的构造方法就可以
public D2() {
super("哈哈");//调用父类的构造方法
System.out.println("我是D2无参数构造方法");
}
public D2(String name) {
super("哈哈");//调用父类的构造方法
System.out.println("我是D2有参数构造方法");
}
}
5.super和this和final
1.this:表示本类的对象
super:在子类中表示的是父类对象
super可以在子类中调用父类的方法(使用this也可以调用)
public class Day07 {
public static void main(String[] args) {
TestB b = new TestB();
b.fn();
//输出
{
num1 = 10;
num2 = 30;
}
}
}
class TestA{
int num1 = 10;
int num2 = 20;
}
class TestB extends TestA{
int num2 = 30;
public void fn() {
//系统会先从本类中寻找该属性,找到就输出没找到就父类中找,都没找到就报错
System.out.println(num1);
System.out.println(num2);//就近原则
System.out.println(super.num2);//super表示父类的对象
}
}
2.关键字final
1.修饰变量 变量值不能更改,变为常量
2.修饰方法 方法不能被重写
3.修饰类 该类不能被继承
public class Demo09 {
public static void main(String[] args) {
final int a = 10;
//a = 15;
//final 修饰引用数据类型
//不能修改地址(对象的属性可以修改)
final Test3 test3 = new Test3();
test3.name = "李四";
test3.name = "张三";
//final修饰保存的内存地址不能被修改
test3 = new Test3();
}
}
//用final修饰类,该类不能被继承
final class Test3{
//声明静态常量
//命名规范 所有单词使用大写,多个单词使用下划线连接
public static final int MAX_VAlue = 10;
//可以使用构造方法或构造代码块对常量进行赋值
//用final修饰方法,方法不能被重写
final public void fn() {
}
}
//报错父类用final修饰,不能被继承
class Test4 extends Test3{
@Override
public void fn() {
// TODO Auto-generated method stub
super.fn();
}
}
三.方法的重写
1.方法的重载(Overload):
当方法的功能相同内部实现不同时使用,前提是方法都在一个类中
方法的重写(Override)
前提:类与类之间必须建立继承关系
作用:相对于原方法功能上的一个提升
写法:方法和父类完全一致,才是方法的重写
public class Day07 {
public static void main(String[] args) {
Test2 t1 = new Test2();
t1.fn();//直接输出对象的时候,希望可以把对象的所有成员变量输出
}
}
class Test1{
String name;
public void fn() {
System.out.println("我是Test1的fn");
}
}
class Test2 extends Test1{
//重写fn方法
@Override
public void fn() {
//可以在重写方法中 调用父类原方法
//可以让功能升级
//重写object类中toString方法
//可以代替之前的sayHi方法,输出对象的所有的成员变量
@Override
public String toString() {
// TODO Auto-generated method stub
return "name" + super.name ;
}
super.fn();
System.out.println("我是test2的fn方法");
}
}