JavaSE——类与对象(2)

一、代码块

代码块是使用{}定义的一段代码
代码块分为普通代码块、构造块、静态块和同步代码块
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)如果发现类名称上出现了".",应当立即想到内部类的概念。
因此,内部类不作为设计的首选

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

扫描二维码关注公众号,回复: 699535 查看本文章
 
 
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。



猜你喜欢

转载自blog.csdn.net/l_x_y_hh/article/details/79931782