向上投射对象时,哪些部分涉及父级,哪些部分涉及子级?

问题描述

在下面的示例中,我对为何向上转换似乎引用父类的某些部分以及实际类的某些部分感到困惑。

CREATE TABLE public.sensors(
  id SERIAL PRIMARY KEY,type VARCHAR(50),location VARCHAR(50)
);
​
-- Postgres table
CREATE TABLE sensor_data (
  time TIMESTAMPTZ NOT NULL,sensor_id INTEGER,temperature DOUBLE PRECISION,cpu DOUBLE PRECISION,FOREIGN KEY (sensor_id) REFERENCES sensors (id)
);
​
--drop table public.sensor_data;
​
-- TimescaleDB table
CREATE TABLE sensor_data_ts (
  time TIMESTAMPTZ NOT NULL,FOREIGN KEY (sensor_id) REFERENCES sensors (id)
);
SELECT create_hypertable('sensor_data_ts','time');
​
-- Insert Data
​
INSERT INTO sensors (type,location) VALUES
('a','floor'),('a','ceiling'),('b','ceiling');
​
​
-- Postgres 
​
INSERT INTO sensor_data (time,sensor_id,cpu,temperature)
SELECT
  time,random() AS cpu,random()*100 AS temperature
FROM generate_series(Now() - interval '50 week',Now(),interval '5 minute') AS g1(time),generate_series(1,4,1) AS g2(sensor_id);
​
-- TimescaleDB
INSERT INTO sensor_data_ts (time,1) AS g2(sensor_id);
​
​
--truncate table public.sensor_data;
--truncate table public.sensor_data_ts;
​
select count(*) from public.sensor_data sd ;
select count(*) from public.sensor_data_ts sd ;
​
--Postgres
​
--Aggregate queries
SELECT 
  floor(extract(epoch from "time")/(60*60*24*2)) as period,AVG(temperature) AS avg_temp,AVG(cpu) AS avg_cpu 
FROM sensor_data 
GROUP BY period;
--ORDER BY PERIOD;

--Join Queries
SELECT 
  sensors.location,floor(extract(epoch from "time")/(60*60*24*7)) as period,last(temperature,time) AS last_temp,AVG(cpu) AS avg_cpu 
FROM sensor_data JOIN sensors on sensor_data.sensor_id = sensors.id
GROUP BY period,sensors.location;
​
--Timescale DB
​
--Aggregate Queries
SELECT 
  time_bucket('2 day',time) AS period,AVG(cpu) AS avg_cpu 
FROM sensor_data_ts 
GROUP BY period;
--ORDER BY PERIOD;
​
--Join Queries
SELECT 
  sensors.location,time_bucket('1 week',sensors.location;

打印结果为:

public class B extends A{
   int fi = 15;
   public static void main(String[] args){
       B b = new B();
       b.fi = 20;
       System.out.println(b.fi);
       System.out.println(  (  (A) b  ).fi  );
       System.out.println(  (  (A) b  ).getNum());
   }
   public int getNum(){
       return fi;
   }
}
class A{
   final int fi = 5;
   public int getNum(){
       return fi * 2;
}

我知道这段代码是用一些低效的方式编写的,但是它类似于我所得到的OCA练习问题。我想知道为什么((A)b).fi指向A中的变量,但是((A)b).getNum()使用B中的变量和方法。如果向上转换指向父级,则不应结果改为20 5 20 吗?

解决方法

这里有两种作用力:

一方面,Java编译器使用引用的类型将名称解析为类成员。因为((A)b)的类型为A

  • ((A)b).fi引用A中的变量fi
  • ((A)b).getNum()指的是A中的方法getNum。例如,您可以在A.getNum()声明中添加 checked异常来查看事实。将异常排除在B.getNum()之外。编译器将要求您捕获或声明((A)b).getNum()可能引发的异常,而编译器则允许您在不进行此类更改的情况下调用b.getNum()

另一方面,Java具有方法的动态分配。动态分派意味着在运行时,JVM会查看实际对象的类型是什么。如果对象 overrides 您正在调用的方法,则JVM会调用覆盖。这意味着:

  • ((A)b).getNum()将在运行时调用B中定义的方法。
,

方法是由动态类型(B)选择的,而属性是由静态类型(A)选择的。

也许其中一个链接可以为您提供帮助: