在Java中,使用{}括起来的代码被称为代码块。
根据位置和声明不同进行分类:
指在类的方法里写的代码块;
public class Test {
public static void main(String[] args) {
System.out.println("我是局部代码块1");
System.out.println("我是局部代码块3");
System.out.println("我是局部代码块2");
}
}
运行结果:
我们在main方法和普通的类的方法中都是可以自定义代码块的,由上边结果,我们可以看出,局部代码块是按照定义的顺序来执行的.
我们在类中创建的代码块,并加上了static修饰符修饰;
注:静态代码块的功能是用来初始化类的,因此在加载的时候就可以执行,并且只执行一次;
public class Test {
public static String static_init;
public static void main(String[] args) {
System.out.println("我是变量static_init="+static_init);
System.out.println("我是局部代码块1");
System.out.println("我是局部代码块3");
System.out.println("我是局部代码块2");
}
static{
System.out.println("这是静态代码块!");
static_init = "在静态代码块中执行了初始化";
}
}
运行结果:
我们可以看到的是输出结果在静态代码块中代码最先执行,但也仅仅执行了一次,并且我们在静态代码中给静态变量赋值,static_init也得到了这个值。
在类中方法出现
public class Test {
public static String static_init;
public static void main(String[] args) {
System.out.println("我是变量static_init="+static_init);
System.out.println("我是局部代码块1");
System.out.println("我是局部代码块3");
CodeTset codeTset = new CodeTset();
codeTset.gouzaoCodeTest();
System.out.println("我是局部代码块2");
codeTset.gouzaoCodeTest();
}
static{
System.out.println("这是静态代码块!");
static_init = "在静态代码块中执行了初始化";
}
}
class CodeTset{
public void gouzaoCodeTest() {
System.out.println("我是构造代码块");
}
}
运行结果:
构造代码块是我们在类中定义的,当实例化对象的时候会被自动调用,且每次调用都执行。
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
注:当描述事物的时候有几个类有重复的属性和方法的时候,可以采用继承的方法来设计。
通过extends关键字可以实现类与类之间的继承
class 子类名 extends 父类名{
}
(1). 提高了代码的复用性;
(2). 提高了代码的维护性;
实例:
Cat类:
属性:姓名(name)、年龄(age)
方法:吃(eat)、睡觉(sleep)
class Cat{
//属性:姓名(name),年龄(age)
String name = "猫";
int age = 6;
//行为:吃饭(eat),睡觉(sleep)
public void eat(){
System.out.println(name+"吃饭");
}
public void sleep(){
System.out.println(name+"睡觉");
}
}
Dog类:
属性:姓名(name)、年龄(age)
方法:吃(eat)、睡觉(sleep)
class Cat{
//属性:姓名(name),年龄(age)
String name = "狗";
int age = 6;
//行为:吃饭(eat),睡觉(sleep)
public void eat(){
System.out.println(name+"吃饭");
}
public void sleep(){
System.out.println(name+"睡觉");
}
}
从上面两个代码可以看出,代码重复度相当高,而且还只有两个方法,若涉及更多的方法时,代码冗余度就会相当高,所以,此时引入继承,将两个代码提出一个父类。
Animal类:
属性:年龄(age)
方法:吃(eat)、睡觉(sleep)
class Animal{
//属性:年龄(age)
int age = 6;
//行为:吃饭(eat),睡觉(sleep)
public void eat(String name){
System.out.println(name+"吃饭");
}
public void sleep(String name){
System.out.println(name+"睡觉");
}
}
Cat类:
属性:姓名(name)
class Cat extends Animal{
//属性:姓名(name)
String name = "猫";
}
Dog类:
属性:姓名(name)
class Dog extends Animal{
//属性:姓名(name)
String name = "狗";
}
开发原则:高内聚,低耦合
耦合:类与类之间的关系,简单说就是代码之间联系的紧密程度;
内聚:自己完成某件事的能力;
继承的缺点就是提高了代码的耦合度,使得代码的独立性变差。
· Java只支持单继承,不支持多继承,但可以支持多重继承;
public class A{...}
public class B extends A{...}
public class C extends B{...}
子类可以继承父类非private的属性和方法;
子类可以对父类进行扩展,即子类可以拥有父类没有的方法;
子类中的成员变量和父类中的成员变量名称不一样;
子类中的成员变量和父类中的成员变量名称一样;
在子类中访问一个变量的查找顺序(“就近原则”)
在子类的方法的局部范围找,有就使用;
在子类的成员范围找,有就使用;
如果还找不到,就报错;
super.成员变量 //调用父类的成员变量
super.成员方法 //调用父类的成员方法
this.成员变量 //调用本类的成员变量
this.成员方法 //调用本类的成员方法
public class Test1 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eatTest();
}
}
class Animal{
public void eat(){
System.out.println("吃饭");
}
}
class Dog extends Animal{
public void eat() {
System.out.println("吃骨头");
}
void eatTest(){
this.eat();//调用自己的方法
super.eat();//调用父类的方法
}
}
final关键字声明类可以把类定义为不能继承的,即最终类;
final class A{
}
final关键字用于修饰方法,该方法不能被子类重写;
修饰符(public/private) final 返回值类型 方法名(){
}
final关键字用于修饰变量,被修饰的变量不能重新赋值,用final修饰相当于将这个量变为常量。
重载(Overload)是指:在一个类里面,名字相同,而参数不同(参数的数量不同或者数量相同而类型和次序不同)的多个方法。
public class Test2 {
public static void main(String[] args) {
Overloadaing overloadaing = new Overloadaing();
overloadaing.make();
overloadaing.make("桃子");
overloadaing.make("橙子", 1);
overloadaing.make(1, "橘子");
}
}
class Overloadaing{
//没有参数
public void make(){
System.out.println("白开水");
}
//有参数
public void make(String s ){
System.out.println("水蜜桃汁");
}
//以下是有两个参数,但是顺序不同
public void make(String str, int i){
System.out.println("橙子汁");
}
public void make(int i, String str){
System.out.println("橘子汁");
}
运行结果:
根据以上代码,我们将重载简析:加入你又一个榨汁机,除了水是必需品之外:
1.什么都不用,那你出来就是白开水;
2.你用的是桃子,那么出来就是水蜜桃汁;
3.你先放入的橙子,然后加点其他作料,此处用1表示,那么出来就是橙子汁;
4.你先放入其他作料,然后加入橘子,出来就是橘子汁;
返回的值都是能喝的东西,但是具体使用哪个方法来执行,就要根据你的原材料和原材料的顺序来决定。
所以,可以跟你局传递进去参数的不同,决定具体使用什么函数,来提高函数使用的灵活性。
(以下规则参考菜鸟教程)
重写是子类对父类里边允许自己访问的方法进行重新的编写,返回值和形参都不能改变。
在我们认知的继承关系中,子类可以继承父类到中的方法而不需要单独编辑,但是有时候,子类不想原封不动的继承父类的方法,而是想做一定的修改,这就是所谓的方法重写;
public class Test4 {
public static void main(String[] args) {
Animal dog = new Dog();
dog.eat();
}
}
class Animal{
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
运行结果:
在上述实例中,尽管dog属于Animal类,但是它运行的是Dog类的eat方法,这是因为在编译阶段,看的是父类,运行的时候,看的是子类,当然前提是Animal类中存在eat方法。###
(参考菜鸟教程)
比较项 | 位置 | 方法名 | 参数表 | 返回值 | 访问修饰符 |
---|---|---|---|---|---|
方法重写 | 子类 | 相同 | 相同 | 相同或是其子类 | 不能比父类更严格 |
方法重载 | 同类 | 相同 | 不相同 | 无关 | 无关 |
以上又可以划分为三类:
1.概念上:重载是一个类里面相同名称不同参数的方法;重写是继承中的子类对父类方法的构造;
2.范围上:重载在一个类里,重写是在有继承关系的类里;
3.权限要求:重载没有权限要求,子类重写权限必要>=父类(比如父类是default。子类就只能是public或者default)。