java第七天/10.15

来源:互联网 发布:无人机与人工智能 编辑:程序博客网 时间:2024/05/17 21:46

一、代码块
概念:
使用{}括起来的代码,成为代码块。
分类:
根据它位置和声明的不同,我们可以将代码块分为局部代码块,构造代码块,静态代码块,同步代码块(多线程涉及)

a、局部代码块
限定了变量的生命周期,变量在局部代码块中定义的,那么出来局部代码块之后,就访问不到了。在局部代码块中定义的变量,在出了代码块之后,内存就会释放掉。
作用:主要节约内存
局部代码块中定义的变量,虽然说作用域是局部的,但是如果存在外部嵌套的代码块,且在局部代码块定义之前就定义了某个变量,
那么在我们局部的代码块中就不可以定义相同名称的变量。
但是如果在局部代码块执行之后,去定义一个和局部代码块中相同名称的变量,是可以的。因为局部代码块中的变量已经失去了作用域范围。
例:
public static void main(String[] args){
int x=10;
{
int x=20;
}
}
出错
————————————————
public static void main(String[] args){
{
int x=20;
}
int x=10;
}
正确,jvm释放掉局部内存
b.构造代码块
概念:
类中方法外出现,每次调用构造方法的时候,都会优先先调用构造代码块。

特点:
每创建一个对象,都会调用一次我们的构造代码块.

作用:
如果存在很多重载的构造方法,而且每个里面需要执行 相同的逻辑,那么就可以考虑将这些代码提取到构造代码块中来执行。
让我们代码结构更简练。增强了维护性.
使用场景其实不太多见。
例:
public class Demo2{
public static void main(String[] args){
Person person = new Person();
System.out.println(“——————–”);
Person person1 = new Person(20);
}
}
class Person{
int age;
int[] num;
{
//构造代码块
System.out.println(“构造代码块”);
}
//默认的构造方法
Person(){
System.out.println(“默认构造”);
// 数组成员变量我们依次赋值
}
Person(int age){
this.age = age;
System.out.println(“非默认构造”);
// 数组成员变量我们依次赋值
}
}
这里写图片描述
c.静态代码块
概念:
类中方法外出现,但是用static 来进行修饰。

特点:
随着类加载的时候执行。

用处:
适用于整个软件的生命周期中,只需要执行一次的业务逻辑代码。
比如我们之后数据库的操作.
例:
public class Demo2{
static{
System.out.println(“demo2 静态代码块”);
}
public static void main(String[] args){
Person person = new Person();
System.out.println(“——————–”);
Person person1 = new Person(20);
}
}
class Person{
int age;
int[] num;
static{
System.out.println(“调用了静态代码块”);
}
{
//构造代码块
System.out.println(“构造代码块”);
}
//默认的构造方法
Person(){
System.out.println(“默认构造”);
// 数组成员变量我们依次赋值
}
Person(int age){
this.age = age;
System.out.println(“非默认构造”);
// 数组成员变量我们依次赋值
}
}
这里写图片描述
二. 继承
特点
1. 子类继承父类,继承父类的成员变量和成员方法。但是他们各自拥有的各自的成员变量,所以他们的值,并不会继承。
2. 对于父类中的私有成员变量和私有方法,子类是无法继承的。
例:
package java_study;

public class ExtendsDemo1 {
public static void main(String[] args){
Son son=new Son();
son.setName(“sunshine”);
son.setAge(20);
son.speak();
}
}
class Father{
private int age;
private String name;
void setAge(int age){
this.age=age;
}
int getAge(){
return age;
}
void setName(String name){
this.name=name;
}
String getName(){
return name;
}
void speak(){
System.out.println(“father speak”+name+” “+age);
}
}
class Son extends Father{
}
这里写图片描述
继承优点:
a.提高了代码的复用性
b.提高了代码的维护性
继承缺点:
类的耦合性增强了。
开发的原则:
高内聚,低耦合.

耦合: 类和类之间的关系
内聚: 自己独立完成某件事情的能力.
3.只支持单继承,但是可以支持多层继承
继承是相互叠加的,子类继承的时候,会递归似的寻找父类中是否还存在继承,会继承整个层级直到最根部类的属性和方法。
package _01.org.westos;

public class ExtendsDemo2 {
public static void main(String[] args){
GrandFather grandFather=new GrandFather();
grandFather.speak();
Father father=new Father();
father.speak();
father.eat();
Son son=new Son();
son.speak();
son.eat();
son.sleep();
}
}
class GrandFather{
void speak(){
System.out.println(“GrandFather speak”);
}
}
class Father extends GrandFather{
void eat(){
System.out.println(“Father eat”);
}
}
class Son extends Father{
void sleep(){
System.out.println(“Son sleep”);
}
}
这里写图片描述
4.对于构造方法是无法继承的。
但是有办法可以调用父类的构造方法。
继承关系中访问成员变量:

a.不同名的成员变量
子类可以直接访问和使用父类继承的非私有的成员变量

b.同名的成员变量
优先原则: 如果子类中定义了和父类中相同名字的成员变量,会优先访问子类的该变量
如果想要依然访问到父类中的同名变量,我们需要加上super关键字来获取.
public class ExtendsDemo3{
public static void main(String[] args){
Son son = new Son();
//System.out.println(son.num3);
son.print();
}
}
class Father{
int num1 = 10;
int num2 = 20;
}
class Son extends Father{
int num3 = 30;
int num1 = 40;
//num1是子类中定义的一个和父类同名的变量。
void print(){
System.out.println(this.num1+” .. “+this.num2);
System.out.println(super.num1+” .. “+super.num2);
}
}

this: 当前对象的引用
super: 父类对象的引用

this: 可以访问到子类中的变量,也可以访问到父类中的变量
super: 访问父类中的变量

继承关系中访问成员方法:
a.不同名的方法
子类可以直接调用到父类的方法

b.同名的方法
当父类和子类出现同名方法的时候(同名方法: 指的返回值类型(父子类关系是可以的),方法名称以及方法接收的形参列表要一模一样)

在这种情况下:
当我们子类调用该方法时,会有优先原则的处理,就是会调用子类的该方法。

方法的重写:
存在于继承关系中,子类中定义的方法和父类中的方法完全一样的时候(返回值类型父子类关系是可以的),我们在通过子类对象来
访问该方法的时候,就会调用到子类的方法。

方法重写注意事项:
子类不能重写父类的私有方法.
子类重写父类方法的时候,提供的访问权限不能更低.
子类覆盖父类方法,如果父类是静态方法的话,子类也必须是静态方法才可以成功覆盖,也就是重写。

方法重载:
同一个类中,如果我们有多个相同方法名的方法,但是他们的形参列表是不同的,那么这种方式我们就称为方法的重载。
在调用的时候,jvm能够通过不同的形参来区分到我们到底调用的是哪个方法。

关于方法重写和方法重载的返回值约束:
方法重载: 仅返回值不同是不能重载的。必须参数列表不同。
方法重写: 返回值类型(父子类关系是可以的) 要求返回值类型也要相同的.

this: 可以访问子类的方法,也可以访问父类的方法。
super: 只能够访问父类的方法。

补充:
我们一个文件在编译之后产生的.class 文件的数量,取决于在该文件中定义的class的数量。(非内部类)
而且是不引入其他类的情况下。

继承中构造方法的调用:
特点:
1. 创建子类对象的时候,一定会优先去创建父类的对象。 因为要创建父类对象,所以就需要去调用到父类的构造方法.
2. 对于我们所有的类的构造方法的第一行,第一行在我们没有自己添加this(…)或者super(…)的情况下都会去帮我们默认的添加
super()

如果父类中不存在默认的构造,子类依然要创建对象,那么子类就需要显示的指明调用的是哪一个父类对象,才能保证父类对象
创建的成功。

明确一点:
a.一定要保证父类对象的创建成功.
b.构造方法的第一行,如果我们添加了自己调用的this(…),或者super(…), 系统就不会为我们默认的添加super().
c.我们的this(…)或者super(…) 必须放到第一行。二者只能有其一。
public class ExtendsDemo5{
public static void main(String[] args){
Son son = new Son();
System.out.println(“————-“);
}
}
class Father{
/*
Father(){
System.out.println(“father 默认构造”);
}
*/
Father(int num){
System.out.println(“father 有参构造”);
}
}
class Son extends Father{
Son(){
//super(10);
this(10); //this(10), 所以就不会帮我们再去默认添加super(),
System.out.println(“son 默认构造”);
}
Son(int num){
super(10);
//super(10); //第一行没有this或者super,就会帮我们添加super()
System.out.println(“son 有参构造”);
}
}
这里写图片描述

三. final关键字

a.final修饰类
final如果修饰一个类,该类不能被继承.

b.final修饰类的成员变量
该成员变量的值不可修改。
问题: 那么什么时候初始化这个值?

在对象创建之前都可以.
a.构造代码块中可以进行初始化
b.构造方法中可以进行初始化
c.定义成员变量的时候,可以直接进行初始化.

注意一点: 这三种方式同时只能用一种。

在大多数的场景下,我们的final成员变量都会配合public static 一起使用.

//常量类, 变量命名都要大写,而且单词之间要用_分割开.
class A{
public static final double PI = 3.14;
public static final double RATE = 2.86;
}

A.PI
A.RATE
package _01.org.westos;

public class FinalDemo {
public static void main(String[] args){
Person person=new Person();
person.sayNum();
}
}
class Person{
//final 修饰成员变量,该值不可修改
static final int num;
static{
num=10;
}
Person(){
}
void sayNum(){
System.out.println(num);
}
}
这里写图片描述
静态成员变量的初始化时机:
a.在创建静态final成员变量的时候,直接进行初始化。
b.在静态代码块中进行初始化.

练习:
(1)定义一个保存10个int 型的数组,并且初始化为 0-27 的随机值,之后进行升序排序。
package _01.org.westos;
import java.util.*;
public class ClassTest {
public static void main(String[] args){
Random d=new Random();
int []array=new int[10];
for(int i=0;i< array.length;i++){
array[i] = d.nextInt(28);
}
Arrays.sort(array);
System.out.println(Arrays.toString(array));
}
}
这里写图片描述
(2)长方形 继承 正方形
package _01.org.westos;
public class ClassTest1 {
public static void main(String[] args){
Square square=new Square();
System.out.println(square.getSumLength());
System.out.println(square.getArea());
Rectangle rectangle=new Rectangle();
System.out.println(rectangle.getSumLength());
System.out.println(rectangle.getArea());
}
}
class Square{
private int length=10;
int getSumLength(){
return 4*length;
}
int getArea(){
return length*length;
}
}
class Rectangle extends Square{
int width=4;
int height=5;
int getSumLength(){
return (width+height)*2;
}
int getArea(){
return width*height;
}
}
这里写图片描述