JavaSE——类与对象(2)

论坛 期权论坛 脚本     
匿名技术用户   2020-12-28 14:00   11   0

一、代码块

代码块是使用{}定义的一段代码
代码块分为普通代码块、构造块、静态块和同步代码块
1.普通代码块
定义在方法中的代码块,若方法中代码较长,为避免变量重名,使用普通代码块进行分隔

2.构造块
定义在类中的代码块(不加修饰符)
注:构造块优先于构造方法执行,每产生一个新的对象就调用一次构造块,构造块可以进行简单的逻辑操作

3.静态代码块

使用static定义的代码块

(1)在非主类中的静态代码块

1)静态块优先于构造块执行。
2)无论产生多少实例化对象,静态块都只执行一次。

(2)在主类中的静态代码块

在主类中定义的静态块,优先于主方法(main)执行
class Person
{
 {
  System.out.println("1.类中的构造块");
 }
 public Person() {
  System.out.println("2.类中的无参构造,代码块");
 }
 public Person(int i) {
  System.out.println("3.类中的有参构造,代码块");
 }
 static {
  System.out.println("4.类中的静态块");
 }
}
public class Test {
 {
  System.out.println("5.主类中的代码块");
 }
 public Test() {
  System.out.println("6.主类中的无参构造");
 }
 static
 {
  System.out.println("7.主类中的静态块");
 }
 public static void main(String[] args) {
  System.out.println("————start————");
  Test test1=new Test();
  Test test2=new Test();
  Person per1=new Person();
  Person per2=new Person();
  Person per3=new Person(2);
  Person per4=new Person(3);
  System.out.println("———— end ————");
 }
}

上面这段代码执行的结果为
7.主类中的静态块
————start————
5.主类中的代码块
6.主类中的无参构造
5.主类中的代码块
6.主类中的无参构造
4.类中的静态块
1.类中的代码块
2.类中的无参构造,构造块
1.类中的代码块
2.类中的无参构造,构造块
1.类中的代码块
3.类中的有参构造,构造块
1.类中的代码块
3.类中的有参构造,构造块
———— end ————

二、内部类

内部类的特点:
(1)破坏了程序的结构
(2)方便进行私有属性的访问。(外部类也可以访问内部类的私有域)
(3)如果发现类名称上出现了".",应当立即想到内部类的概念。
因此,内部类不作为设计的首选

内部类就是在一个类的内部进行其他类结构的嵌套的操作


class Outter
{
 private String msg= "Hello World";
 class Inner
 {
  public void print()
  {
   System.out.println(msg);
  }
 }
 //需要在内部类外,外部类中定义一个方法,来将内部类进行实例化
 public void fun() 
 {

  Inner inner=new Inner();
  inner.print();
  }
}
public class Test 
{
 public static void main(String[] args) 
 {
  Outter outter=new Outter();
  outter.fun();
  }
}

(1)如果想在程序外部调用,那么必须按照如下形式进行内部类的实例化对象创建
外部类.内部类 内部类对象 = new 外部类().new 内部类();
Outter.Inner in = new Outter().new Inner();
(2)如果说现在一个内部类只想被外部类使用,即:不希望直接产生内部类的实例化对象,可以使用private定义
(3)在进行属性访问时,都需要加上this关键字。所以如果想在内部类中明确的使用this,则格式为
外部类.this.属性

1.static定义内部类
内部类中如果使用了static进行定义。该内部类只允许访问外部类中的static操作。实际上该内部类等同于外部类,产生该内部类的实例化对象语法为
外部类.内部类 内部类对象 = new 外部类.内部类();
class Outter
{
 private static String msg= "Hello World";
 static class Inner
 {
  public void print()
  {
   System.out.println(msg);
  }  
 }
 public void fun() {
  Inner inner=new Inner();
  inner.print();
 }
}
public class Test {
 public static void main(String[] args) {
  Outter.Inner inner=new Outter.Inner();
  inner.print();
 }
}

2.在方法中定义内部类(最常用)
class Outter
{
 private String msg="Hello word";
 public void fun() {
  class Inner
  {
   public void print()
   {
    System.out.println(msg);
   }
  }
  //在方法外部要将内部类进行实例化,并调用方法
  Inner inner=new Inner();
  inner.print();
  
 }
}
public class Test {
 public static void main(String[] args) {
  Outter outter=new Outter();
  outter.fun();
           }
}

三、继承
面向对象的第二大特征:继承。

1)继承的主要作用在于,消除结构定义上的重复,在已有基础上继续进行功能的扩充,以及代码的重用。
2)子类对象的实例化流程:不管如何操作,一定要先实例化父类对象。
3)不允许多重继承,只允许多层继承。
1.继承的实现
继承使用extends关键字来实现,子类也称为派生类,父类也称为超类
class 子类 extends 父类
class Person
{
 private String name;
 private int age;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 
}
class Student extends Person
{
 private String sex;

 public String getSex() {
  return sex;
 }

 public void setSex(String sex) {
  this.sex = sex;
 }
 
}
public class Test {
 public static void main(String[] args) {
  Student student=new Student();
  student.setName("LLL");
  student.setAge(11);
  student.setSex("m");
  System.out.println("name"+student.getName()+"age"+student.getAge()+"sex"+student.getSex());
 }
}
当发生了类继承关系之后,子类可以直接继承父类的操作,可以实现代码的重用

2.继承的限制
(1)子类对象在进行实例化前一定会首先实例化父类对象。默认调用父类的构造方法后再调用子类构造方法
进行子类对象初始化
(2)如果父类里没有提供无参构造,那么这个时候就必须使用super()明确指明你要调用的父类构造
方法
class Person
{
 public Person() {
  System.out.println("1父类无参构造");
  
 }
 public void print() {
  System.out.println("2父类的普通方法");
 }
 
 
}
class Student extends Person
{
 public Student() {
  super.print();//指明了这个构造方法继承的是父类的print方法
      //若此句不写,则student类就是一个普通类,就不是person类的子类
  System.out.println("3子类的无参构造");
  
 }
 public Student(int i) {
  System.out.println("4子类的有参构造");
  
 }
 public void fun()
 {
  super.print();
  System.out.println("5子类的普通方法");
 }
}
public class Test {
 public static void main(String[] args) {
  Student student1=new Student();//1 2 3
  Student student2=new Student(1);//1 4
  student1.fun();//2 5
 }
}

3.Java不允许多重继承,但是允许多层继承
(1)一个子类只能继承一个父类,C同时继承A和B的主要目的是同时拥有A和B中的操作,为了实现这样的目的,可以采用多层继承的形式完成
class A{}
class B extends A{}
class C extends B{}

(2)在进行继承的时候,子类会继承父类的所有结构。(包含私有属性、构造方法、普通方法)但是这个时候需要注意的是,所有的非私有操作属于显示继承(可以直接调用),所有的私有操作属于隐式继承(通过其他形式调用,例如setter或getter)

四、覆写
如果子类定义了与父类相同的方法或属性的时候,这样的操作就称为覆写

1.方法的覆写

子类定义了与父类方法名称、参数类型及个数完全相同的方法称为覆写。但是被覆写不能够拥有比父类更为严格的访问控制权限。
(1)覆写的语句


class Person{
public void print() 
{ 
 System.out.println("1父类的普通方法");
 } 
}
class Student extends Person
{ 
 public void print() 
 { 
  System.out.println("2子类对父类普通方法print的覆写"); 
  }
}
public class Test 
{ 
 public static void main(String[] args) 
 { 
  Student student=new Student();//2 
  student.print(); 
 }
}

1)只需要关注当前使用的对象是通过哪个类new的。
2)当调用某个方法,如果该方法已经被子类所覆写了,那么调用的一定是被覆写过的方法。
(2)覆写的权限
在进行方法覆写的时候,有明确的要求:被覆写不能够拥有比父类更为严格的访问控制权限。现在,见到的权限比较有private<default<public。那么也就意味着如果父类使用public进行方法声明,那么子类必须也使用public;如果父类使用default,那么子类可以使用default或者public。也就是说,覆写的子类方法的权限一定要大于等于被覆写的父类的方法权限。
注:父类使用private定义的方法,子类不能覆写
class Person
{
 private void print() 
 {
  //如果父类的方法是用private定义,则表示该方法只能被父类使用,子类无法覆写
  System.out.println("2父类的普通方法");
  }
 }
class Student extends Person
{
 public void print() 
 {
  //此时只是在子类中重新定义了一个叫print的方法,根本没有对父类进行覆写
  System.out.println("子类想要对父类普通方法print的覆写,结果覆写失败");
  }
 }
public class Test 
{
 public static void main(String[] args)
 {
  Student student=new Student();
  student.print();
  }
}
(3)覆写与重载的区别
2.属性的覆写
当子类定义了和父类属性名称完全相同的属性的时候,就成为属性的覆盖

class Person
{ 
 public String name="LLL";
}
class Student extends Person
{ 
 public String name ="HHH";
}
public class Test 
{
 public static void main(String[] args) 
 { 
  Student student=new Student(); 
  System.out.println("name"+student.name); 
 }
}

3.super关键字

(1)在继承时,子类调用父类构造方法时使用
(2)在进行覆写时使用 super.方法() 或者 super.属性 明确调用父类中的方法或属性
class Person
{ 
 public String mString="父类属性"; 
 public void print() 
 {  
  System.out.println("父类方法"); 
  }
}
class Student extends Person
{ 
 public String mString="子类属性"; 
 public void print() 
 {  
  super.print();//在子类方法中调用父类方法  
  System.out.println(super.mString);//在子类方法中调用父类属性 
  System.out.println("子类方法");  
  System.out.println(this.mString);   
  }
}
public class Test 
{ 
 public static void main(String[] args) 
 {  
  Student student=new Student();  
  student.print(); 
 }
}

(3)this关键字和super关键字的区别


注:能使用super.方法()一定要明确标记出是父类的操作
(1)子类覆写父类的方法是因为父类的方法功能不足才需要覆写。
(2)方法覆写的时候使用的就是public权限

五、final关键字

在Java中final被称为终结器,可以使用final来定义类、方法、属性。
(1)使用final来定义类
使用final定义的类不能有子类(String类便是使用final定义)
final class A{} //A类不能有子类
(2)使用final来定义方法
使用final定义的方法不能被子类所覆写。
class A{
public final void fun(){}
}
(3)使用final来定义属性
使用final定义的变量就成为了常量,常量必须在声明时赋值,并且不能够被修改。
publc final int LEVEL_A = 100 ;

六、多态性

1. 方法的多态性
(1)方法的重载:同一个方法名称可以根据参数的类型或个数不同调用不同的方法体
(2)方法的覆写:同一个父类的方法,可能根据实例化子类的不同也有不同的实现。
2. 对象的多态性【抽象类和接口才能体会到实际用处】(前提:方法覆写):
【自动,90%】①对象的向上转型:父类 父类对象 = 子类实例。
【强制,1%】②对象的向下转型:子类 子类对象 = (子类)父类实例。
(1)向上转型
class Person
{
 public void print()
 {
  System.out.println("1.父类普通方法");
 }
}
class Student extends Person
{
 public void print()
 {
  System.out.println("2.子类普通方法对父类进行覆写");
 }
}
public class Test {
 public static void main(String[] args) {
  Person person=new Student();//向上转型
  person.print();
 }
}

(2)向下转型
向下转型指的是将父类对象变为子类对象,当需要子类扩充操作的时候就要采用向下转型
class Person
{
 public void print()
 {
  System.out.println("1.父类普通方法");
 }
}
class Student extends Person
{
 public void print()
 {
  System.out.println("2.子类普通方法对父类进行覆写");
 }
 public void fun()
 {
  System.out.println("子类特有的方法");
 }
}
public class Test {
 public static void main(String[] args) {
  Person person=new Student();//向上转型(自动)
  person.print();
  Student student=(Student) person;//向下转型(强转)在向下转型之前,一定要进行向上转型
  student.fun();
 }
}

若向下转型具有安全隐患,则需要用instanceof关键字进行判断
public class Test {
 public static void main(String[] args) {
  Person person=new Student();//向上转型(自动)
  person.print();
  if(!(person instanceof Student ))
  {
   person =new Student();
   Student student=(Student) person;
   student.fun();
  }
}

注:
(1)对象多态性的核心在于方法的覆写。
(2)通过对象的向上转型可以实现接收参数的统一,向下转型可以实现子类扩充方法的调用
(2)两个没有关系的类对象是不能够进行转型的,一定会产生ClassCastException。



分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP